Строка в DateTime в C # для сохранения на сервере SQL - PullRequest
0 голосов
/ 22 апреля 2010

У меня проблема при преобразовании «16-17 марта» в DateTime и сохранении его на SQL-сервере.«16-17 марта», как он выглядит, читается как 16-17 марта, что в моем случае недопустимо, но C # DateTime.TryParse () трактует «16-17 марта» как 16 марта 2017 года, что неправильно, исохранение данных на сервере SQL.SQL-сервер считает «16-17 марта» недействительным.Итак, может ли кто-нибудь сказать мне, как использовать проверку даты и времени на SQL-сервере в C #.

Спасибо Ashwani

Ответы [ 4 ]

4 голосов
/ 22 апреля 2010

Звучит так, как будто значение вообще не должно быть DateTime. Вместо этого это должна быть строка (varchar / nvarchar) или два значения DateTime (начало и конец). То есть, почему вы пытаетесь сначала позвонить DateTime.TryParse или DateTime.TryParseExact? Если вы хотите сохранить их как даты, вам нужно будет заставить пользователей вводить их как даты (как в двух значениях даты в вашем примере), а затем вы можете легко сохранить их как даты. Если вы хотите разрешить пользователям вводить «16-17 марта» или «Весна 2010» или «Последняя половина марта», используйте тип данных varchar или nvarchar.

РЕДАКТИРОВАТЬ Учитывая то, что вы сказали в комментариях, похоже, что вы передаете XML напрямую в SQL Server и надеетесь, что SQL Server проанализирует даты. К сожалению, SQL Server не так хорош, как вы обнаружили. IMO, было бы проще перестроить XML в C #, проверяя и анализируя даты и целые числа, прежде чем передавать его в SQL Server. Т.е., я бы постарался сделать как можно меньше таких разборов и проверок в SQL Server. Если вы все еще хотите пойти по этому пути, другим решением было бы создать функцию CLR (что означает, что CLR должен быть включен), которая предоставила бы вам ту же функциональность парсинга даты, что и C #.

РЕДАКТИРОВАТЬ После долгих обсуждений кажется, что проблема в том, что синтаксический анализатор C # слишком умен для ваших целей. Вы хотите, чтобы C # аннулировал дату, как SQL Server. Я могу придумать пару способов решить это:

  • Отправить длинный список разрешенных форматов методу DateTime.TryParseExact. Недостатком является то, что с точки зрения разбора значений даты это гораздо менее простительно.
  • Запустите TryParse и подтвердите год. Если год X число лет после этого года, то признайте его недействительным.
  • Найдите способ заставить источник XML принудительно применять даты, чтобы отправлялись только действительные даты.
  • Напишите подпрограмму, которая определяет, имеет ли дата какую-то неожиданность, например 16-17 (хотя 03-16-17 следует считать действительной, поэтому вам нужно быть осторожным), прежде чем передавать ее в TryParse.

Попытка фактически использовать синтаксический анализ даты SQL Server не будет работать, если вы не поместите данные в символьный столбец, а затем не используете функции SQL Server IsDate и Cast для заполнения столбца DateTime после заполнения данных.

4 голосов
/ 22 апреля 2010

Синтаксический

Вы можете использовать DateTime.TryParseExact, чтобы проанализировать строку в DateTime, требуя, чтобы она была в точном формате. Это устранит проблему, заключающуюся в том, что вы сможете проанализировать недопустимую дату в экземпляре DateTime.

Вот пример:

        DateTime dt;
        if (DateTime.TryParseExact("March 16", "MMMM dd", new CultureInfo("en-GB"), DateTimeStyles.None, out dt))
            Console.WriteLine(dt);

Если пропустить год, TryParseExact будет считать текущий год. Если вы передадите «16-17 марта» этому методу, он потерпит неудачу. Параметр IFormatProvider является английской культурой, поэтому мы можем считать «март» 3-м месяцем года.

Как вы заметили, это не то же самое, что делает SQL Server. Как он конвертирует даты, будет зависеть от настроек сортировки. Я бы не рекомендовал это, но если вам действительно, действительно нужно точно воспроизвести эту функциональность и использовать ее из C #, вы можете создать хранимую процедуру, которая принимает varchar, выполняет преобразование и возвращает DateTime - и позвоните из C #.

Вы также можете использовать метод DateTime.TryParse для анализа даты в C #. Этот метод также принимает IFormatProvider, который сообщает платформе, как выполнять анализ. IFormatProvider реализован CultureInfo, поэтому, если вы передадите CultureInfo, который соответствует параметрам сортировки SQL Server, где вы наблюдали желаемое поведение, есть вероятность, что результаты анализа будут похожими. Наконец, вы можете сделать собственную реализацию IFormatProvider, если вы не удовлетворены встроенными возможностями.

Мои комментарии

Ваша настоящая проблема заключается в том, что вы фактически делаете проверку и преобразование из строки в DateTime дважды. Оказавшись в C #, вы отправляете строку на SQL Server и снова преобразуете ее. Это может создать проблемы, поскольку, как вы заметили, две системы анализируют одинаково, но не совсем одинаково в крайних случаях.

Я думаю, вам следует выполнить проверку и синтаксический анализ в C #, а затем отправить полученный DateTime на SQL Server в виде объекта DateTime, поэтому самому SQL Server не требуется выполнять анализ. Вы можете сделать это с помощью параметризованных запросов в ADO .NET - если вы используете что-то другое для доступа к данным, будет аналогичная функция.

1 голос
/ 22 апреля 2010

Я понимаю, что вы не хотите ограничивать своих пользователей. Похоже, вы делаете что-то вроде этого:

mySqlCommand.CommandText = "UPDATE tbl SET date_field = @parm";
string maybeDate = "March 16-17");
DateTime dt;
if (DateTime.TryParse(maybeDate, dt)
{
    mySqlCommand.Parameters.AddWithValue("@parm", maybeDate)
}

Можете ли вы сделать это вместо этого?

mySqlCommand.CommandText = "UPDATE tbl SET date_field = @parm";
string maybeDate = "March 16-17");
DateTime dt;
if (DateTime.TryParse(maybeDate, dt)
{
    mySqlCommand.Parameters.AddWithValue("@parm", dt); // <============
}
0 голосов
/ 22 апреля 2010

Он считает, что 17 - это 2017, потому что годы можно записать двумя цифрами, попробуйте ввести четыре

if (DateTime.TryParseExact("March 16-17", "MMMM dd YYYY", new CultureInfo("en-GB"), DateTimeStyles.None, out dt))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...