Проверьте DateTime перед тем, как вставить его в базу данных SQL Server. - PullRequest
20 голосов
/ 14 августа 2011

Есть ли способ проверить поле datetime перед его вставкой в ​​соответствующую таблицу?

Попытка вставки с помощью блока try / catch не подходит.

Спасибо,

Ответы [ 9 ]

30 голосов
/ 14 августа 2011

Не уверен, что я слишком педантичен, но DateTime.TryParse проверит, является ли значение допустимым объектом DateTime. ОП спросил о проверке значения перед вставкой в ​​SQL Server datetime. Диапазон допустимых значений для SQL Server datetime составляет «1 января 1753 года - 31 декабря 9999 года», что не относится к объектам DateTime .NET. Этот сценарий присваивает значению «1/1/0001 12:00:00 AM» для badDateTime, и он успешно анализирует.

DateTime d = DateTime.MinValue;
string badDateTime = DateTime.MinValue.ToString();
Console.WriteLine(badDateTime);
DateTime.TryParse(badDateTime, out d);

Однако, если вы попытаетесь сохранить это в поле datetime, произойдет сбой с сообщением «Преобразование типа данных varchar в тип данных datetime привело к значению вне допустимого диапазона.»

Комментатор спросил, почему я использовал 997 для миллисекунд, это покрывается SQL Server 2008 и миллисекундами , но, сохраняя вас, клик, 997 - это самое большое значение, которое вы можете сохранить в типе данных datetime. 998 будет округлено до 1 секунды с точностью до 000 миллисекунд

    /// <summary>
    /// An initial pass at a method to verify whether a value is 
    /// kosher for SQL Server datetime
    /// </summary>
    /// <param name="someval">A date string that may parse</param>
    /// <returns>true if the parameter is valid for SQL Sever datetime</returns>
    static bool IsValidSqlDatetime(string someval)
    {
        bool valid = false;
        DateTime testDate = DateTime.MinValue;
        DateTime minDateTime = DateTime.MaxValue;
        DateTime maxDateTime = DateTime.MinValue;

        minDateTime = new DateTime(1753, 1, 1);
        maxDateTime = new DateTime(9999, 12, 31, 23, 59, 59, 997);

        if (DateTime.TryParse(someval, out testDate))
        {
            if (testDate >= minDateTime && testDate <= maxDateTime)
            {
                valid = true;
            }
        }

        return valid;
    }

Это, вероятно, лучший подход, так как он попытается преобразовать объект DateTime в фактический тип данных sql datetime


    /// <summary>
    /// An better method to verify whether a value is 
    /// kosher for SQL Server datetime. This uses the native library
    /// for checking range values
    /// </summary>
    /// <param name="someval">A date string that may parse</param>
    /// <returns>true if the parameter is valid for SQL Sever datetime</returns>
    static bool IsValidSqlDateTimeNative(string someval)
    {
        bool valid = false;
        DateTime testDate = DateTime.MinValue;
        System.Data.SqlTypes.SqlDateTime sdt;
        if (DateTime.TryParse(someval, out testDate))
        {
            try
            {
                // take advantage of the native conversion
                sdt = new System.Data.SqlTypes.SqlDateTime(testDate);
                valid = true;
            }
            catch (System.Data.SqlTypes.SqlTypeException ex)
            {

                // no need to do anything, this is the expected out of range error
            }
        }

        return valid;
    }
17 голосов
/ 14 октября 2014

Попробуйте это без жесткого кодирования sql dateTime value:

    public bool IsValidSqlDateTime(DateTime? dateTime)
    {
        if (dateTime == null) return true;

        DateTime minValue = DateTime.Parse(System.Data.SqlTypes.SqlDateTime.MinValue.ToString());
        DateTime maxValue = DateTime.Parse(System.Data.SqlTypes.SqlDateTime.MaxValue.ToString());

        if (minValue > dateTime.Value || maxValue < dateTime.Value)
            return false;

        return true;
    }
2 голосов
/ 12 ноября 2014
<asp:RangeValidator runat="server" ID="rgvalDate" ControlToValidate="txtDate" Text="[Invalid]" Type="Date" MinimumValue="1/1/1753" MaximumValue="12/31/9999" />

OR

пользовательский валидатор:

    protected void cvalDOB_ServerValidate(object sender, ServerValidateEventArgs e)
    {
        e.IsValid = IsValidSqlDateTime(e.Value);
    }

    public static bool IsValidSqlDateTime(object Date)
    {
        try
        {
            System.Data.SqlTypes.SqlDateTime.Parse(Date.ToString());
            return true;
        }
        catch
        {
            return false;
        }
    }
2 голосов
/ 03 декабря 2013

Это еще один вариант ответа биллинка.Однако в этом методе свойство .Value min / max используется, чтобы избежать синтаксического анализа и try / catch.Кто-то упомянул, что хочет убедиться, что вставляет правильную дату в SQL Server.Итак, я выбрал способ возврата даты, которая действительна для SQL Server.Это можно легко изменить на логический метод, который проверяет, является ли dateToVerify действительной датой SQL Server.

protected DateTime EnsureValidDatabaseDate(DateTime dateToVerify)
{
    if (dateToVerify < System.Data.SqlTypes.SqlDateTime.MinValue.**Value**)
    {
        return System.Data.SqlTypes.SqlDateTime.MinValue.Value;
    }
    else if (dateToVerify > System.Data.SqlTypes.SqlDateTime.MaxValue.**Value**)
    {
        return System.Data.SqlTypes.SqlDateTime.MaxValue.Value;
    }
    else
    {
        return dateToVerify;
    }
}
1 голос
/ 02 мая 2018

Вот класс с методом расширения, разрешающим проверку, например if(myDateTime.IsValidSqlDateTime()) { ... }:

public static class DateTimeExtensionMethods
{
    public static bool IsValidSqlDateTime(this DateTime dateTime)
    {
        return !(dateTime < (DateTime) SqlDateTime.MinValue ||
                 dateTime > (DateTime) SqlDateTime.MaxValue);
    }
}
1 голос
/ 14 августа 2011

Не могли бы вы предоставить дополнительную информацию о том, откуда поступает значение datetime;веб-форма?Вы можете просто добавить CompareValidator следующим образом

<asp:CompareValidator ID="CompareValidator1" runat="server" 
            ControlToValidate="txtDate" 
            Type="Date" 
            ErrorMessage="CompareValidator">
</asp:CompareValidator>
1 голос
/ 14 августа 2011

DateTime.TryParse лучший валидатор

DateTime temp;
if(DateTime.TryParse(txtDate.Text, out temp))
//Works
else
// Doesnt work
1 голос
/ 14 августа 2011

Если вы упоминаете о проверке поля DateTime на стороне сервера, используйте DateTime.TryParse.Быстрый и грязный пример будет

DateTime dateValue;
string dateString = "05/01/2009 14:57:32.8";
if (DateTime.TryParse(dateString, out dateValue))
{
    // valid date comes here.
    // use dateValue for this
}
else
{
    // valid date comes here
}
0 голосов
/ 14 августа 2011

Вы можете использовать SqlCommand с параметром для предотвращения SQLInjection

Например:

SqlCommand cmn = new SqlCommand("UPDATE table SET date = @Date ");
// cmn set Here....
cmn.Parameters.Add("@Date",SqlDbType.DateTime).Value = dateTimeObj;

и другие данные, которые вы можете просмотреть в MSDN

...