4

Trying to set a datetime field in a SQL table to NULL if the textbox is empty, I can't seem to get this to work.

        string EndDate = "";
        if (String.IsNullOrEmpty(EndDateTxtBox.Text.Trim()))
        {
            EndDate = null;
        }
        else
        {
            EndDate = EndDateTxtBox.Text;
        }

        var sql = String.Format(@"UPDATE Test SET StartDate='{0}', 
                                 EndDate='{1}' WHERE ID = '{2}'",
                                 StartDateTxtBox.Text, EndDate, id);

When I do this and put in a break point I get this for "var sql':

"UPDATE Test SET StartDate='5/23/2013', EndDate=" WHERE ID = '19'"

I tried removing the ' from the sql string but that didn't work either. Any suggestions?

Edit: I understand the importance of preventing against SQL injection but this a page on my internal web server for my use only and not projected to the public. It's to help me keep track of personal things.

4

5 回答 5

12

参数化。

首先,您应该将 UI 代码从数据库代码中移开,以便当它到达数据库附近的任何地方时,我们已经正确输入了数据。例如:

void UpdateDates(int id, DateTime startDate, DateTime? endDate) {...}

并将Parse您想要的任何其他代码放在调用者处- 不在数据库附近。现在我们需要实现它:

void UpdateDates(int id, DateTime startDate, DateTime? endDate) {
    //... where-ever cmd comes from, etc
    cmd.CommandText =
        "update Test set StartDate=@start, EndDate=@end where ID = @id";
    cmd.Parameters.AddWithValue("id", id);
    cmd.Parameters.AddWithValue("start", startDate);
    cmd.Parameters.AddWithValue("end", (object)endDate ?? DBNull.Value);
    cmd.ExecuteNonQuery();
    // ... cleanup etc
}

或者使用像“dapper”这样的工具:

void UpdateDates(int id, DateTime startDate, EndDate? endDate) {
    //... where-ever connection comes from, etc
    connection.Execute(
        "update Test set StartDate=@start, EndDate=@end where ID = @id",
        new { id, start = startDate, end = endDate}); // painfully easy
    // ... cleanup etc
}
于 2013-06-10T15:18:28.377 回答
1

听起来问题出在单引号上。如果它是 NULL 那么你不应该拥有它们。

此外,您可能希望使用参数化查询(出于安全原因并传入值)。在这种情况下,引号也不应该是必需的。

于 2013-06-10T15:20:55.763 回答
0

我认为错误在string.format line. 您不能在字符串部分中包含换行符。尝试以下方法之一。

 var sql = String.Format(
          @"UPDATE Test SET StartDate='{0}', EndDate='{1}' WHERE ID = '{2}'",
           StartDateTxtBox.Text, EndDate, id);

或者,

    var sql = String.Format(@"UPDATE Test SET StartDate='{0}', " + 
                             "EndDate='{1}' WHERE ID = '{2}'",
                             StartDateTxtBox.Text, EndDate, id);

但是,正如这里的其他答案所提到的,您应该了解 SQL 注入并考虑另一种方法。

于 2013-06-10T15:14:50.580 回答
0

尽管代码中的问题不被视为 C# 代码中的 SQL 最佳实践,但您有几个问题:

  1. 您将 EndDate 设置为 C# null。这与 SQL NULL 不同,它表示为 DBNull.Value

  2. 您不考虑 NULL 在 SQL 中不需要引号这一事实,因此即使您修复了 #1,您的 SQL 也必须有所不同才能正常工作。

我建议写一个存储过程;如果结束日期文本框为空,则不要传递该参数,并使其在存储过程中具有默认值 NULL。

Create Procedure usp_TestDateRange_Update
( @ID int -- or whatever type your ID is
  @StartDate DateTime,
  @EndDate DateTime = NULL)
As 
  Update Test
  Set StartDate = @StartDate,
      EndDate = @EndDate
  Where ID = @ID

类似的东西。现在您需要做的是让您的 C# 代码调用存储过程并将参数添加到来自文本框的调用。

于 2013-06-10T15:24:26.870 回答
0

你可以这样试试:

string sql = String.Format(@"UPDATE Test SET StartDate={0}, 
                                     EndDate={1} WHERE ID = {2}",
                     (StartDateTxtBox.Text.Trim().Equals(string.Empty) ? StartDateTxtBox.Text:"NULL"), EndDate, id);
于 2015-10-13T16:08:47.000 回答