Выполнение хранимых процедур с параметрами даты: объект команды и объект соединения

При передаче дат хранимой процедуре через параметр я немного запутался в том, какой формат использовать для дат. Мой исходный синтаксис VBA использовал объект ADO Connection для выполнения хранимой процедуры:

Set SentDetailRS = Me.ADOConnectionToIntegrity.Execute("dbo.s_SelectAggregatedSentDetailList '" & fCSQLDate(EffectiveDate) & "'", , adCmdText)

Это отлично работает для меня, используя синтаксис даты yyyy-mm-dd, но когда другой пользователь выполняет код, он получает ошибку: 13 «Несоответствие типов».

После некоторых экспериментов я обнаружил, что предоставление даты в формате dd/mm/yyyy исправляет эту ошибку для пользователя, но теперь выдает ошибку мне!

Выполнение хранимой процедуры с использованием командного объекта с параметрами работает независимо от формата даты (я предполагаю, что ADO заботится о форматировании за кулисами). Я думал, что использование формата yyyy-mm-dd будет универсально работать с SQL Server?

Я также озадачен тем, почему эта проблема кажется специфичной для пользователя? Я заметил, что мой язык по умолчанию в SQL Server — «английский», тогда как язык другого пользователя по умолчанию — «британский английский». Может ли это вызвать проблему?

Я использую ADO 2.8 с Access 2003 и SQL Server 2000, вход в SQL Server осуществляется через встроенную систему безопасности Windows.


person Community    schedule 17.09.2008    source источник


Ответы (6)


Будьте осторожны и не верьте, что ADO решает проблему. Универсальный формат даты SQL — «ГГГГММДД», в то время как SQL и ACCESS зависят от региональных настроек машины в том, как они отображают даты и преобразуют их в строки символов.

Не забывайте, что разделителем даты является # в Access, а в SQL - '

Мой лучший совет будет систематически преобразовывать ваш доступ #MM-DD-YYYY# (или аналогичный) в 'YYYYMMDD' перед отправкой инструкции на ваш сервер. Вы можете создать небольшую функцию, например:

Public function SQLdateFormat(x_date) as string

SQLDateFormat = _
   trim(str(datePart("yyyy",x_date))) & _
   right(str(datePart("m",date)),2) & _
   right(str(datePart("d",date)),2)

   ''be carefull, you might get something like '2008 9 3'
SQLDateFormat = replace(functionSQLDateFormat," ","0")
   '' you will have the expected '20080903'

End function

Если вы не создадите строку INSERT/UPDATE программно перед ее отправкой на сервер, я посоветую вам изменить региональные настройки всех машин на региональные настройки машины, на которой размещен SQL. Возможно, вам также придется проверить, есть ли на вашем SQL-сервере определенный формат даты (я не уверен). Лично я решил такие проблемы локализации (это также происходит, когда запятая используется в качестве десятичного разделителя во французском языке) или проблемы, связанные со специфическими символами SQL (когда кавычки или двойные кавычки находятся в строке), отменяя инструкции SQL перед отправкой их в сервер.

person Philippe Grondier    schedule 17.09.2008

Я предполагаю, что функция fCSQLDate зависит от культуры, т.е. она будет анализировать дату на основе настроек локали пользователя. Вот почему вы видите проблему.

В любом случае, использование запросов с конкатенированными строками всегда плохая идея (инъекционные атаки). Вам лучше, если вы используете параметры.

person Sunny Milenov    schedule 17.09.2008

Access использует # в качестве разделителя поля даты. Формат должен быть #mm/dd/yyyy#, возможно, #mm-dd-yyyy# также подойдет.

person GUI Junkie    schedule 17.09.2008

Извините, я не знаю mysql, но с оракулом я всегда буду явно указывать формат, в котором я ожидал формат, например: «ДД-ММ-ГГГГ», чтобы избежать (региональных) проблем с форматом даты.

person hamishmcn    schedule 17.09.2008

Почему бы не использовать формат

dd mmm yyyy

Это можно интерпретировать только одним способом.

person Mark Plumpton    schedule 17.09.2008

Вы можете использовать функцию Date() для возврата универсальной даты на основе настроек даты и времени машины. Настройки региона на машине будут определять, как она отформатирована на стороне клиента. Если вы оставите поле как строгое поле DateTime, тогда настройки региона cleint могут отформатировать дату.

При входе на сервер использование функции Date() также должно работать (возвращая универсальное значение даты).

Кроме того, используйте объект команды и параметры в своем запросе, когда вы передаете их, чтобы избежать атак SQL-инъекций на строковые поля.

person Community    schedule 12.06.2009