Как лучше всего запрашивать даты в SQL, когда параметризованные запросы невозможны

Мое краткое описание заключается в реализации интерфейса с методом, который выглядит примерно так: «GetValuesSqlStatement» ниже:

public string SqlPattern { get { ... } }
//this varies; eg. "SELECT name FROM someTable WHERE startDate < {0}"

public string DatabaseType { get { ... } }
//this varies; eg. "SqlServer"

public string GetValuesSqlStatement(List<object> paramValues)
{
    //...desired logic here, using DatabaseType, SqlPattern and paramValues
}

Теперь, поскольку это должно создать исполняемый оператор SQL, я не могу использовать параметры при выполнении запроса. И интерфейс, который я должен реализовать, не подлежит обсуждению. Каков наилучший способ убедиться, что даты в результате правильно интерпретируются механизмом запросов к базе данных? Предполагая, что paramValues ​​​​содержат объекты .NET DateTime, как их следует отформатировать в строку перед подключением к строке шаблона SQL? Каков наиболее распространенный универсальный формат даты в обязательных базах данных? (например, что-то вроде «дд-ммм-гггг»).

NB: мне действительно нужно беспокоиться только о Sql Server с 2005 года и Oracle 10g. Таким образом, SQL должен быть действительным T SQL и PL SQL и означать одно и то же в обоих вариантах.


person Lisa    schedule 23.09.2011    source источник


Ответы (3)


Я думаю, что единственным однозначным форматом даты для SQL Server является ГГГГММДД:

Oracle использует нотацию DATE 'YYYY-MM-DD':

http://download.oracle.com/docs/cd/B19306_01/server.102/b14200/sql_elements003.htm#BABGIGCJ

Хотя может быть нотация, которая работает для обоих в некоторых сценариях, я сомневаюсь, что есть такая, которая работает для обоих со всеми возможными региональными настройками сервера.

Как вы сказали, YYYY-MON-DD может быть полезным - это значение по умолчанию для Oracle.

person Cade Roux    schedule 23.09.2011
comment
Ну, у меня есть строка DatabaseType, которая поможет мне построить этот запрос. Если вы говорите, что «гггг-мм-дд» работает для всех, кроме SQL Server, я могу использовать условную логику. Если «yyyy-mon-dd» работает как в SQL Server, так и в Oracle, этого, конечно, будет достаточно для моих нужд, но я думаю, что это не обязательно будет лучшей практикой. - person Lisa; 23.09.2011
comment
@ Лиза, тебе придется поэкспериментировать. У меня никогда не было французских серверов, и я всегда использую ГГГГ-ММ-ДД. Вы увидите в статье Аарона и этом элементе подключения, что он не применяется к новым типам данных date и datetime2. в SQL-сервере. По моему опыту работы с Oracle, литералам всегда требуется квалификатор DATE, чтобы отличить их от строк. Вероятно, вам нужно обернуть генерацию строки даты чем-то, что специфично для БД. - person Cade Roux; 23.09.2011
comment
У меня внезапно появилась идея получше, что делает этот вопрос не таким уж полезным. Я мог бы добавить его как третий ответ, даже если он строго не отвечает на вопрос. - person Lisa; 23.09.2011

Если вы используете формат даты «гггг-мм-дд» с любой БД, все должно быть в порядке. Это соответствует стандарту ISO 8601 ( http://www.iso.org/iso/date_and_time_format).

person mal-wan    schedule 23.09.2011
comment
В SQL Server проблемы остаются sqlblog.com/blogs/aaron_bertrand/archive/2009/10/16/ (Подключение connect.microsoft.com/SQL/feedback/) - person Cade Roux; 23.09.2011
comment
Я думаю, что это будет самое универсальное, что вы можете получить. Знаете ли вы локализацию ваших серверов? - person mal-wan; 23.09.2011
comment
По всему миру. Хорошо для этого конкретного проекта будет +8GMT или +9.30GMT, но мы не можем допустить, чтобы он внезапно не работал для другого клиента. - person Lisa; 23.09.2011
comment
@mwan Я считаю, что все серверы должны быть настроены в единой истинной, данной Богом инвариантной культуре Соединенных Штатов, все даты в формате ГГГГ-ММ-ДД, все числа в формате 9 999 999,99 и размещены по Гринвичу. Но я не понимаю своего, поэтому мне приходится искать голландские серверы, поддерживающие польские номера формы 9 999,99. ;-) - person Cade Roux; 23.09.2011

Я даю на это свой собственный ответ, хотя он выходит за рамки вопроса, потому что это может быть полезным предложением для других с аналогичным вопросом.

Я только что понял, что могу просто ожидать, что каждый экземпляр (или каждый клиент в другой части мира) необязательно укажет строку формата в последней части заполнителя параметра. Например. выполнение:

public string SqlPattern { get {
    return "SELECT name FROM someTable WHERE startDate < {0:yyyy-mm-dd}";
} }  

И тогда моему компоненту вообще не нужно беспокоиться о том, как отформатировать дату. По умолчанию я могу использовать «ггггммдд» или, что еще лучше, просто использовать культуру сервера, чтобы выбрать значение по умолчанию. В противном случае используйте пользовательский шаблон. Это был бы общий подход, применимый к другим типам, которые также необходимо преобразовать в строку для SQL.

person Lisa    schedule 23.09.2011