过滤两个日期之间的数据,出现以下错误:
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();
我无法解决此错误。
答案 0 :(得分:1)
每当发现将.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;