System.Data.SqlClient.SQLException: преобразование типа данных varchar в время данных - PullRequest
0 голосов
/ 29 апреля 2019

Отфильтровав данные между двумя датами, я получил следующую ошибку:

System.Data.SqlClient.SqlException: преобразование данных varchar тип данных типа дата / время, приведший к выходу за пределы допустимого диапазона.

Мой код:

con.Open();
SqlCommand cmd = con.CreateCommand();
cmd.CommandType = CommandType.Text;
cmd.CommandText = "SELECT daytime AS DATE, COLUMN_2 AS SHIFT, COLUMN_3 AS 'PART NO',COLUMN_4 AS 'PART NAME',BSNO AS 'BASKET NUMBER',Spare1 AS MATERIAL, CAS6 AS 'CASCADE RINSE 6 TIME (sec)',DRY AS 'DRYER TIME (sec)',TEMP1 AS 'DRYER TEMP (°c)' FROM Table_2 WHERE daytime BETWEEN '" + dateTimePicker1.Value.ToString() + "' AND '" + dateTimePicker2.Value.ToString() + "'";
cmd.ExecuteNonQuery();
DataTable dt = new DataTable();
SqlDataAdapter da = new SqlDataAdapter(cmd);
da.Fill(dt);
metroGrid1.DataSource = dt;
con.Close();

Я не могу решить эту ошибку.

1 Ответ

1 голос
/ 29 апреля 2019

Всякий раз, когда вы обнаруживаете, что преобразовываете значение .Net DateTime в строку для использования в SQL, вы что-то делаете ОЧЕНЬ неправильно.

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

//most datetime comparisons want an *exclusive* upper bound, but the BETWEEN operator bounds are inclusive on both ends
var sql = "SELECT daytime AS DATE, COLUMN_2 AS SHIFT, COLUMN_3 AS 'PART NO',COLUMN_4 AS 'PART NAME',BSNO AS 'BASKET NUMBER',Spare1 AS MATERIAL, CAS6 AS 'CASCADE RINSE 6 TIME (sec)',DRY AS 'DRYER TIME (sec)',TEMP1 AS 'DRYER TEMP (°c)' FROM Table_2 WHERE daytime >= @daytimeStart AND daytime < @daytimeEnd ;";
var dt = new DataTable();

//Don't try to re-use your connection object. 
// ADO.Net connection pooling means you should create a new connection for most queries
using (var con = new SqlConnection("connection string here"))
using (var cmd = new SqlCommand(sql, con))
using (var da = new SqlDataAdapter(cmd))
{  //These using blocks guarantee the connection is closed, **even if an exception is thrown**. The original code would have left the connection open if you had an exception.

    //This is the correct way to include user data with your sql statement
    // **NEVER** use string concatenation to substitute values into SQL strings
    cmd.Parameters.Add("@daytimeStart", SqlDbType.DateTime).Value =  dateTimePicker1.Value;
    cmd.Parameters.Add("@daytimeEnd", SqlDbType.DateTime).Value =  dateTimePicker2.Value;

    //the Fill() method opens and closes the connection as needed
    da.Fill(dt);
}
metroGrid1.DataSource = dt;

Здесь снова без лишних комментариев, поэтому вы можете видеть, что новый шаблон не намного длиннее, чем исходный код в вопросе:

var sql = "SELECT daytime AS DATE, COLUMN_2 AS SHIFT, COLUMN_3 AS 'PART NO',COLUMN_4 AS 'PART NAME',BSNO AS 'BASKET NUMBER',Spare1 AS MATERIAL, CAS6 AS 'CASCADE RINSE 6 TIME (sec)',DRY AS 'DRYER TIME (sec)',TEMP1 AS 'DRYER TEMP (°c)' FROM Table_2 WHERE daytime >= @daytimeStart AND daytime < @daytimeEnd ;";

var dt = new DataTable();
using (var con = new SqlConnection("connection string here"))
using (var cmd = new SqlCommand(sql, con))
using (var da = new SqlDataAdapter(cmd))
{   
    cmd.Parameters.Add("@daytimeStart", SqlDbType.DateTime).Value =  dateTimePicker1.Value;
    cmd.Parameters.Add("@daytimeEnd", SqlDbType.DateTime).Value =  dateTimePicker2.Value;

    da.Fill(dt);
}
metroGrid1.DataSource = dt;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...