System.Data.SqlClient.SQLException:将 varchar 数据类型转换为 datetime

Posted

技术标签:

【中文标题】System.Data.SqlClient.SQLException:将 varchar 数据类型转换为 datetime【英文标题】:System.Data.SqlClient.SQLException: The conversion of a varchar data type to datatime 【发布时间】:2019-04-29 13:38:09 【问题描述】:

过滤两个日期之间的数据我收到以下错误:

System.Data.SqlClient.SqlException: varchar 数据的转换 type 到 datetime 数据类型导致超出范围。

我的代码是:

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();

我无法解决这个错误。

【问题讨论】:

始终使用 SQL 参数并传递日期而不转换为字符串。 非常自我解释,您的日期时间不是 SQL 有效的。这两个日期的值是多少?使用调试模式并找出答案。此外,您应该使用参数而不是这样构建 SQL 语句。 SQL - The conversion of a varchar data type to a datetime data type resulted in an out-of-range value的可能重复 【参考方案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;

这里再次没有额外的 cmets,因此您可以看到新模式没有明显长于问题中的原始代码:

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;

【讨论】:

以上是关于System.Data.SqlClient.SQLException:将 varchar 数据类型转换为 datetime的主要内容,如果未能解决你的问题,请参考以下文章