将varchar数据类型转换为datetime数据类型导致了一个超出范围的值错误。

4
将varchar数据类型转换为datetime数据类型时出现了超出范围值的错误。
我正在尝试使用表单向我的表中输入数据,表单验证和SQL Server中的日期格式都是dd/mm/yy。但是,当我尝试提交一个大于12的日期(例如13/12/2012)时,它会抛出异常,原因是“将varchar数据类型转换为datetime数据类型时出现了超出范围值的错误”。如果我尝试以mm/dd/yy格式输入数据,则会显示“日期格式错误”,这意味着dd/mm/yy格式是正确的格式。
以下是我的表单代码:
    private void btnAddProject_Click(object sender, EventArgs e)
    {
        DateTime startDate;
        DateTime endDate;

        if (txtProjectName.Text == "") //client side validation
        {
            MessageBox.Show("Enter Project Name");
            return;
        }

        try
        {
            startDate = DateTime.Parse(txtProjectStart.Text);
            endDate = DateTime.Parse(txtProjectEnd.Text);
        }
        catch (Exception)
        {
            MessageBox.Show("Wrong Date Format");
            return;
        }
        fa.CreateProject(txtProjectName.Text, startDate, endDate, (int)cbCustomers.SelectedValue, ptsUser.Id);
        txtProjectName.Text = "";
        txtProjectStart.Text = "";
        txtProjectEnd.Text = "";
        cbCustomers.SelectedIndex = 0;
        MessageBox.Show("Project Created");
        adminControl.SelectTab(2);
    }// end btnAddProject

这是我的DAO中的代码:

public void CreateProject(string name, DateTime startDate, DateTime endDate, int customerId, int administratorId)
    {
        string sql;
        SqlConnection cn;
        SqlCommand cmd;
        Guid projectId = Guid.NewGuid();

        sql = "INSERT INTO Project (ProjectId, Name, ExpectedStartDate, ExpectedEndDate, CustomerId, AdministratorId)";
        sql += String.Format("VALUES('{0}', '{1}', '{2}', '{3}', {4}, {5})", projectId, name, startDate, endDate, customerId, administratorId);

        cn = new SqlConnection(Properties.Settings.Default.WM75ConnectionString);
        cmd = new SqlCommand(sql, cn);

        try
        {
            cn.Open();
            cmd.ExecuteNonQuery();
        }
        catch (SqlException ex)
        {
            throw new Exception("Error Creating Project", ex);
        }
        finally
        {
            cn.Close();
        }

    }//end CreateProject Method

这是我的Facade代码:

public void CreateProject(string name, DateTime startDate, DateTime endDate, int customerId, int administratorId)
    {
        dao.CreateProject(name, startDate, endDate, customerId, administratorId);
    }//end CreateProject
3个回答

13

您可以像sqldatetime一样进行sqldatetime转换。

 var sqlFormattedDate = myDateTime.Date.ToString("yyyy-MM-dd HH:mm:ss");

11

基本上,在你的SQL中,你不应该使用DateTime值作为字符串传递。使用参数化的SQL,直接设置参数值即可。尽可能使用参数化的SQL:

  • 它提供更好的代码/数据分离
  • 它避免了问题转换(如此例)
  • 它避免了SQL注入攻击

此外,你的异常处理过于复杂。只需使用using语句,并让SqlException直接抛出——何必将其包装在普通的Exception中呢?


-2
sql = "INSERT INTO Project (ProjectId, Name, ExpectedStartDate, ExpectedEndDate, CustomerId, AdministratorId)";
sql += String.Format("VALUES('{0}', '{1}', '{2}', '{3}', {4}, {5})", projectId, name, startDate.toString("dd-MMM-yyyy"), endDate.toString("dd-MMM-yyyy"), customerId, administratorId);

一个建议:为什么在你的代码中使用Insert语句?你可以使用存储过程代替。

没有必要使用存储过程 - 或者至少,您没有提出任何可以带来好处的建议。只需使用参数化SQL即可解决此问题。 - Jon Skeet
那是一个糟糕的解决方案。一个更好的解决方案是避免不必要的字符串转换。 - Jon Skeet
然后您可以使用CulturInfo。 - PQubeTechnologies
在插入语句中尝试将startDate转换为datetime类型,格式为103。 - PQubeTechnologies
为什么要进行转换呢?没有必要。源值是“DateTime”,目标值是与日期有关的字段。为什么要使用字符串来使事情变得复杂呢? - Jon Skeet
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接