Я создаю динамический запрос как хранимую процедуру в SQL Server 2008 и получаю неожиданные результаты при сравнении даты (предоставленной в качестве параметра) и даты и времени (хранящейся в базе данных). Я искал несколько способов сравнить их, не принимая во внимание временную часть, и нашел это:
DATEDIFF(day, @d, v.ScheduledDate) = 0
Что я делаю с этим, так это пытаюсь найти записи, в которых предоставленный параметр даты и сохраненная ScheduledDate совпадают (с точки зрения дней, например, 05.02.2011 и 05.02.2011 11 :26:19.157). Это запрос, который я написал для этого:
SET @sql = 'SELECT e.Id, e.FirstName, e.LastName, v.ScheduledDate
FROM Employee e, Visit v
WHERE 1=1'
-- Several IF IS NOT NULL statements here
IF @d IS NOT NULL
BEGIN
SET @sql = @sql + ' AND DATEDIFF(day, ''' + @d + ''',' + 'v.ScheduledDate) = 0
AND v.EmpId = e.Id '
END
EXEC (@sql)
Я ожидаю, что этот запрос приведет ко всем запланированным датам для любого сотрудника, визит которого запланирован на этот день. Другими словами, если у меня есть два сотрудника с идентификаторами 5 и 7, а в таблице посещений есть две записи ScheduleDate от 05.02.2011 для сотрудников с идентификаторами 5 и 7, я ожидаю, что оба этих сотрудника вернутся, когда я запустите этот запрос. Однако кажется, что когда я запускаю его, я возвращаю только одну строку. (В качестве примечания: две записи ScheduledDate, с которыми я работаю, относятся к одному и тому же дню, но с разницей примерно в 3 часа. Я думаю, что функция DATEDIFF будет учитывать это, поскольку несколько часов, безусловно, находятся в пределах временные рамки дня.) Если я изменяю = в запросе на >= 0 или ‹= 0, я получаю больше строк, как и ожидалось, но, как ни странно, по-прежнему получаю только одну запись для этой конкретной даты. В таблице есть другие записи, в которых один и тот же сотрудник имеет несколько посещений в разные даты, и они возвращаются соответственно, когда я использую >= 0 или ‹= 0. Например, сотрудник с идентификатором 41 имеет 3 посещения 29.10.2011. , 11-24-2011 и 12-28-2011, и все 3 из них возвращаются, когда я меняю DATEDIFF на >= 0. Я все еще не понимаю, почему я получаю только одну запись, когда два разных сотрудника визит запланирован на тот же день. Может ли кто-нибудь дать некоторое представление о том, где моя логика идет не так, как надо? Обратите внимание, что когда я тестирую это, я задаю только параметр ScheduledDate. Все остальные операторы IF IS NOT NULL просто не выполняются, поскольку все остальные параметры вставляются как NULL.
sp_executesql
, чтобы вы могли параметризовать свои запросы. (Кэшированные планы, безопасность типов, упрощение отладки и т. д.) - person MatBailie   schedule 23.12.2011sp_executesql
, оно позволяет делать вещи более аккуратными и НЕ требует приведения дат к строкам (неявно или иным образом) для создания запроса. Это сужает круг возможных источников ошибок. - person MatBailie   schedule 23.12.2011sp_executesql
. Если я правильно понимаю, устранит ли это необходимость объявлять мой параметр @d как VARCHAR? - person Zajn   schedule 23.12.2011DATEADD(day,DATEDIFF(day,0,@datetime),0)
чтобы удалить время - person KM.   schedule 23.12.2011CAST(@d AS DATE)
, поскольку это SQL Server 2008? - person MatBailie   schedule 23.12.2011LEFT JOIN Visit v on e.Id = v.EmpId
и получили только одну запись, когда ожидали 2. Эта ошибка возникла из-за отсутствия сотрудника в таблице сотрудников, чей визит все еще существовал. Спасибо за вашу помощь всем! - person Zajn   schedule 23.12.2011