简体   繁体   English

我的 SQLParameter 没有正确传递 NULL

[英]My SQLParameter isn't passing NULL correctly

I have this C# webform that has has a date picker box.我有这个具有日期选择器框的 C# 网络表单。 If the date is set to nothing (the default) I want it to pass NULL to the database.如果日期设置为空(默认值),我希望它将 NULL 传递给数据库。 This happens inside my parametrized query.这发生在我的参数化查询中。

SqlParameter CMActionDate = new SqlParameter();
CMActionDate.ParameterName = "@ActionDate";
if (ActionDate.Equals(""))
  {
      CMActionDate.Value = System.Data.SqlTypes.SqlDateTime.Null;
  }
  else
  {
      CMActionDate.Value = ActionDate;
  }

When I turn on debugging I see that the date is indeed "" so it goes into the IF statement and sets the actiondate.value to {Null} like I think it should.当我打开调试时,我看到日期确实是“”,所以它进入 IF 语句并将 actiondate.value 设置为 {Null},就像我认为的那样。

However.然而。

When it then goes to execute the nonquery, I click the magnifying glass and see this:然后当它执行非查询时,我单击放大镜并看到:

UPDATE table SET [action_date] = '' WHERE [id] = 2488

What I would like to see is this:我想看到的是:

UPDATE table SET [action_date] = 'Null' WHERE [id] = 2488

Since the action_date never really gets set to NULL, then the value in the datetime field reverts to "01/01/1900 12:00:00AM" and that's a pain in itself.由于 action_date 从未真正设置为 NULL,因此 datetime 字段中的值将恢复为“01/01/1900 12:00:00AM”,这本身就是一种痛苦。

I have tried setting CMActionDate.Value to the following values to no avail (I get the same result as above.):我尝试将 CMActionDate.Value 设置为以下值无济于事(我得到与上面相同的结果。):

  • DBNull.Value; DBNull.值;
  • "NULL"; “无效的”;
  • SqlDateTime.Null; SqlDateTime.Null;
  • null; null;

Help.帮助。

EDIT编辑

Maybe I wasn't clear?可能我没说清楚? Yes, of course the parametrized query looks like this:是的,参数化查询当然是这样的:

"UPDATE CM_Codebase SET [action_date] = '" + @ActionDate + "' WHERE [id] = " + @CM_id + "";

But when I am debugging this thing in VS, I put a breakpoint right before ExecuteNonQuery();但是当我在 VS 中调试这个东西时,我在 ExecuteNonQuery(); 之前放了一个断点。 so I can see the SQL it's trying to run.所以我可以看到它正在尝试运行的 SQL。 It's there that I see the actual SQL and see the bit where action_date=''.在那里我看到了实际的 SQL 并看到了 action_date='' 的位。

Does that help?这有帮助吗?

You shouldn't see either '' or 'Null'.您不应该看到“”或“空”。 If you're using parameterized queries correctly it should look like this:如果您正确使用参数化查询,它应该如下所示:

UPDATE table SET [action_date] = @ActionDate WHERE [id] = @ID更新表 SET [action_date] = @ActionDate WHERE [id] = @ID

The whole point of a parameterized query is that the actual parameter value is never substituted directly into the query string.参数化查询的重点是实际参数值永远不会直接替换到查询字符串中。

Your query code should look something like this:您的查询代码应如下所示:

string sql = "UPDATE table SET [action_date]= @ActionDate WHERE [id]= @CM_id";

using (var cn = new SqlConnection("your connection string here."))
using (var cmd = new SqlCommand(sql, cn))
{
    cmd.Parameters.Add("@ActionDate", SqlDbTypes.DateTime).Value = 
         ActionDate.Equals("")? DBNull.Value : DateTime.Parse(ActionDate);
    cmd.Parameters.Add("@CM_id", SqlDbTypes.Int).Value = 2488;

    cn.Open();
    cmd.ExecuteNonQuery();
}

The result of this code is that your query parameters are sent to the server as data.此代码的结果是您的查询参数作为数据发送到服务器。 At no point in your C# code will you ever be able to view the query string with your data substituted in: it's sent to the server separately.在您的 C# 代码中,您永远无法查看替换数据的查询字符串:它是单独发送到服务器的。

This prevents any possibility of the server executing a parameter value as code because of an error in sanitizing your parameter value.这可以防止服务器由于清理参数值时出错而将参数值作为代码执行的任何可能性。 The data is completely separate, and doesn't need to be sanitized for that context in the first place.数据是完全独立的,不需要首先针对该上下文进行清理。 It also allows the server to cache and reuse the execution plan for the query, resulting in a (small) performance boost.它还允许服务器缓存和重用查询的执行计划,从而带来(小的)性能提升。

Your parametized query should show您的参数化查询应显示

UPDATE table SET [action_date] = @ActionDate WHERE [id] = @id

And the parameter value should have a null equivalent value.并且参数值应该有一个 null 等效值。

Your sql is你的 sql 是

"UPDATE CM_Codebase SET [action_date] = '" + @ActionDate + "' 
 WHERE [id] = " + @CM_id + "";

Which doesn't really make sense.这真的没有意义。 You should let sql replace the @ActionDate and @CM_ID, not build a dynamic sql query.您应该让 sql 替换 @ActionDate 和 @CM_ID,而不是构建动态 sql 查询。

Your sql should literally be:您的 sql 应该是:

String sql = "UPDATE table SET [action_date] = @ActionDate WHERE [id] = @CM_id"

There should be no string concatenation around the variables, and they should not be wrapped in quotes.变量周围不应该有字符串连接,也不应该用引号引起来。

Your query most certainly does not look like the ones posted.您的查询肯定与发布的查询不同。

Your @parameter needs to be inside your string, in order to be read correctly.您的 @parameter 需要在您的字符串中,以便正确读取。 You are seeing ActionDate = '' because @ActionDate does not exist, most likely.您看到 ActionDate = '' 因为 @ActionDate 很可能不存在。

You need something like你需要类似的东西

string sql = "UPDATE CM_Codebase SET [action_date] = @ActionDate WHERE [id] = @CM_id";

Notice that there is no string concatenation taking place.请注意,没有发生字符串连接。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM