Преобразование не удалось при преобразовании даты и времени из строки символов - PullRequest
0 голосов
/ 26 декабря 2009

Когда я компилирую следующий код, возникает исключение «Преобразование при преобразовании даты и времени из строки символов», что с этим не так?

код:

DateTime after3Dyas = DateTime.Now.AddDays(3);

        try
        {
            Con.Open();
            SqlCommand Command = Con.CreateCommand();
            Command.CommandText = "Select * from Forcast Where City='" + city + "' And Date between '" + DateTime.Now.Date + "' and '" + after3Dyas.Date + "'";

            SqlDataReader thisReader = Command.ExecuteReader();

            int i=0;
            while (thisReader.Read())
            {
                //do something
                i++;

            }

            thisReader.Close();

Ответы [ 4 ]

4 голосов
/ 26 декабря 2009

База данных пытается преобразовать значение из того, что дает DateTime.ToString ... Вы действительно хотите верить, что .NET на вызывающем компьютере и SQL Server используют точно такой же формат? Это звучит хрупко для меня.

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

Пример кода:

DateTime start = DateTime.Now;
DateTime end = start.AddDays(3);
string sql = @"
SELECT * FROM Forecast
WHERE City = @City AND Date BETWEEN @StartDate AND @EndDate";

// Don't forget to close this somewhere. Why not create a new connection
// and dispose it?
Con.Open();
using (SqlCommand command = new SqlCommand(sql, Con))
{
    command.Parameters.Add("@City", SqlDbType.NVarChar).Value = city;
    command.Parameters.Add("@StartDate", SqlDbType.DateTime).Value = start;
    command.Parameters.Add("@EndDate", SqlDbType.DateTime).Value = end;
    using (SqlDataReader reader = command.ExecuteReader())
    {
        int i = 0;
        while (reader.Read())
        {
            //do something
            i++;
        }
    }
}
0 голосов
/ 28 декабря 2009

Вы должны использовать параметризованные запросы, когда это возможно. Есть несколько причин, таких как:

  1. Вы избежите атак SQL-инъекций.
  2. Планы выполнения для параметризованных запросов будут кэшироваться сервером sql, поэтому вы получите лучшую производительность при выполнении одного и того же запроса с разными значениями параметров.
  3. Вы избежите необходимости экранировать строковые параметры.

Для получения более подробной информации см. Следующую статью: http://www.codeproject.com/KB/database/SqlInjectionAttacks.aspx

0 голосов
/ 26 декабря 2009
  1. Вы должны использовать параметризованный запрос.
  2. Если вы не хотите использовать параметризованный запрос, используйте функцию CONVERT:

    "Select * from Forcast Where City='" + city + "' And Date = CONVERT(DATETIME,'" + DateTime.Now.ToString("yyyy-MM-dd") + "',120)

CONVERT(Datetime,'2009-12-25',120) преобразует тип varchar в тип datetime с указанным форматом. Это также поможет с внедрением sql, но параметры - лучшее решение.

0 голосов
/ 26 декабря 2009

Попробуйте использовать приведенный ниже формат:

DateTime.Now.ToString("yyyy-MM-dd") 

Но я настоятельно рекомендую вам использовать параметры из-за проблем безопасности:

Command.CommandText = 
     "Select * from Forcast Where City=@City And Date between @StartDate and @EndDate";

SqlParameter city = new SqlParameter("@City", SqlDbType.VarChar, 10);
city.Value = yourCityValue;
Command.Parameters.Add(city);

SqlParameter startDate = new SqlParameter("@StartDate", SqlDbType.DateTime);
startDate.Value = yourStartDate;
Command.Parameters.Add(startDate);

SqlParameter endDate = new SqlParameter("@EndDate", SqlDbType.DateTime);
endDate.Value = yourEndDate;
Command.Parameters.Add(endDate);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...