我有这个C#webform,它有一个日期选择器框.如果日期设置为空(默认值),我希望它将NULL传递给数据库.这发生在我的参数化查询中.
SqlParameter CMActionDate = new SqlParameter(); CMActionDate.ParameterName = "@ActionDate"; if (ActionDate.Equals("")) { CMActionDate.Value = System.Data.SqlTypes.SqlDateTime.Null; } else { CMActionDate.Value = ActionDate; }
当我打开调试时,我看到日期确实是"",所以它进入IF语句并将actiondate.value设置为{Null},就像我认为的那样.
然而.
然后当它执行非查询时,我点击放大镜看到这个:
UPDATE table SET [action_date] = '' WHERE [id] = 2488
我想看到的是:
UPDATE table SET [action_date] = 'Null' WHERE [id] = 2488
由于action_date从未真正设置为NULL,因此datetime字段中的值将恢复为"01/01/1900 12:00:00 AM",这本身就很痛苦.
我已经尝试将CMActionDate.Value设置为以下值无效(我得到与上面相同的结果.):
DBNull.Value;
"空值";
SqlDateTime.Null;
空值;
救命.
编辑
也许我不清楚?是的,当然参数化查询如下所示:
"UPDATE CM_Codebase SET [action_date] = '" + @ActionDate + "' WHERE [id] = " + @CM_id + "";
但是当我在VS中调试这个东西时,我在ExecuteNonQuery()之前放了一个断点; 所以我可以看到它试图运行的SQL.在那里,我看到了实际的SQL,并看到action_date =''的位置.
这有帮助吗?
你不应该看到''或'Null'.如果您正确使用参数化查询,它应如下所示:
UPDATE表SET [action_date] = @ActionDate WHERE [id] = @ID
在整点参数化查询的是,实际的参数值从不直接代入查询字符串.
您的查询代码应如下所示:
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(); }
此代码的结果是您的查询参数作为数据发送到服务器.在您的C#代码中,您将无法查看以下数据替换的查询字符串:它将单独发送到服务器.
这可以防止服务器执行参数值作为代码的任何可能性,因为清理参数值时出错.数据是完全独立的,并且首先不需要为该上下文进行消毒.它还允许服务器缓存并重用查询的执行计划,从而提高(小)性能.