【问题标题】:"Out-of-range value" error when converting a varchar to datetime将 varchar 转换为日期时间时出现“超出范围值”错误
【发布时间】:2013-05-20 09:22:39
【问题描述】:

我有这个代码

datecreation = todaydate.Substring(6, 4) + todaydate.Substring(3, 2) + 
                   todaydate.Substring(0, 2) 

string sql = "insert into Usertable ";
sql += "values(" + mVendid + ", '" + usrname + "','" + usrpass + "', cast('" + 
datecreation + "'as DATETIME),'" + createdby + "')";

问题是每当它在服务器中运行时都会出错。在本地主机或 SQL 服务器管理中,它工作正常。

到底是什么时候它在网络上不起作用

错误是 varchar 数据类型到日期时间数据的转换 type 导致超出范围的值。该声明已 终止。

【问题讨论】:

    标签: c# sql-server-2008 datetime data-conversion


    【解决方案1】:

    永远不要连接字符串以形成 SQL 查询,始终使用参数化查询。对于您的代码,您可以在命令中使用SqlParameter。无需将 DateTime 转换为字符串,然后在 INSERT 查询中将其转换回 DateTime ,只需在参数中添加 DateTime 对象的值即可。这不仅可以将您从Sql Injection 中解救出来,还可以解决您遇到的问题。

    类似:

    using(SqlConnection conn = new SqlConnection("Connectionstring"))
    using (SqlCommand cmd = new SqlCommand())
    {
        string sql = "insert into Usertable ";
        sql += "values(@mVendid, @usrname, @usrpass, @datecreation, @createdby)";
        cmd.CommandText = sql;
        cmd.Parameters.AddWithValue("@mVendid", mVendid);
        cmd.Parameters.AddWithValue("@usrname", username);
        cmd.Parameters.AddWithValue("@usrpass", userpass);
        cmd.Parameters.AddWithValue("@datecreation", Convert.ToDateTime(datecreation));
        cmd.Parameters.AddWithValue("@createdby", createdby);
        cmd.Connection = conn;
        conn.Open();
        cmd.ExecuteNonQuery();
    }
    

    如果datecreation 来自DateTime 对象,则直接添加它,否则您可以将其解析为DateTime 对象并让SQL Server 为您处理其余部分。

    【讨论】:

      【解决方案2】:

      问题是您的服务器可能与您的机器有不同的语言设置。 为确保转换工作正常,请使用 Convert 函数。完整教程在这里:http://www.sqlusa.com/bestpractices/datetimeconversion/

      顺便说一句,构造像连接字符串这样的查询是非常危险的方式。而不是这个使用 SqlParamerts。此外,使用这种方法的优点是 .NET 将为您进行转换。

      【讨论】:

        【解决方案3】:

        首先是用户参数(更好、更清晰、更安全!)。其次,由于格式问题而发生此错误。

        datecreation = todaydate.Substring(6, 4) + todaydate.Substring(3, 2) + 
                       todaydate.Substring(0, 2) 
        
        string date = DateTime.Parse(datecreation);
        
        string sql = "insert into Usertable values(@mvendid, @username, @usrpass, @date, @createdby)";
        
        var con = new SqlConnection(""); // your connection string
        var cmd = new SqlCommand(sql, con);
        
        cmd.Parameters.AddWithValue("@mvendid", mVendid);
        ...
        cmd.Parameters.AddWithValue("@date", date);
        

        【讨论】:

          【解决方案4】:

          首先,它确实是一个糟糕的查询,而且很hacky,你不应该写这样的查询

          string sql = "insert into Usertable ";
          sql += "values(" + mVendid + ", '" + usrname + "','" + usrpass + "', cast('" + 
          datecreation + "'as DATETIME),'" + createdby + "')";
          

          *始终使用参数化查询 *

          可能会出现错误,因为您将某些文本转换为日期时间。可能的原因日期时间格式不正确 Dateimte 与您的服务器日期时间不匹配 尝试打印出它创造的确切价值

           cast('" + 
              datecreation + "'as DATETIME)
          

          【讨论】:

            【解决方案5】:

            检查服务器的时区。可能与您的本地计算机不同的时区。您可以通过使用参数来避免此问题。

                string sql = @"
            INSERT INTO Usertable 
            VALUES (@Parameter1, @Parameter2, @Parameter3, @Parameter4, @Parameter5)";
            
            (using SqlCommand command = new SqlCommand(sql, myConnection))
            {
                command.Parameters.AddWithValue("@Parameter1", mVendid);
                command.Parameters.AddWithValue("@Parameter2", usrname);
                command.Parameters.AddWithValue("@Parameter3", usrpass);
                command.Parameters.AddWithValue("@Parameter4", todaydate);
                command.Parameters.AddWithValue("@Parameter5", createdBy);
                command.ExecuteNonQuery();
            }
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2020-01-05
              • 1970-01-01
              • 2021-03-25
              • 1970-01-01
              • 1970-01-01
              • 2021-07-26
              • 2023-03-26
              • 1970-01-01
              相关资源
              最近更新 更多