将字符串或NULL插入SQL Server数据库时遇到问题

7

我在编写允许字符串或NULL传递到数据库的正确语法方面遇到了问题。以下是我的代码:

string insertString = String.Format(
    @"INSERT INTO upload_history (field1, field2, field3) 
    VALUES ('{0}', '{1}', '{2}')",
    varField1, varField2, varField3);

我在变量占位符周围使用了单引号,以便数据库可以正确地接受字符串值。但是,如果传递NULL,则会作为字符串“NULL”进入数据库。

有没有一种方法可以在InsertCommand字符串中省略单引号并有条件地向我的变量添加单引号?

3个回答

22

不要使用字符串连接(string.Format),而是使用参数(如@p1等),然后您可以传递DBNull.Value以表示 null 到 SQL Server

SqlCommand cmd = new SqlCommand();
cmd.CommandText = @"INSERT INTO upload_history (field1, field2, field3) 
   VALUES (@p1, @p2, @p3)";
cmd.Parameters.AddWithValue("@p1", (object)someVar ?? DBNull.Value);
//...

这也可以保护您免受SQL注入攻击。


当我像上面那样使用“someVar ?? DBNull.Value”时,我会收到以下错误:“运算符'??'不能应用于类型为string和System.DBNull的操作数”。对于字符串,你有什么想法吗? - buzzzzjay
2
@buzzzzjay 在其中一个前面加上 (object) - Marc Gravell

5

使用String.Format连接字符串可能存在很大的安全风险(SQL注入),并且如果要插入'字符,也会出现问题。

解决方案:

cmd.CommandText = "INSERT INTO upload_history (field1, field2, field3) " +
    "VALUES (@p1, @p2, @p3)";
cmd.Parameters.AddWithValue("@p1", varField1);
cmd.Parameters.AddWithValue("@p2", varField2);
cmd.Parameters.AddWithValue("@p3", varField3);
cmd.ExecuteNonQuery();

这也是一个很好的答案,但Marc已经先你一步了。感谢您的建议。 - beardog

2

为了回答问题并且意识到重构代码以参数化查询是正确的解决方案,你可以编写一个函数,返回单引号字符串或非引用NULL字符串值,然后从查询字符串中删除单引号。

string insertString = String.Format(    @"INSERT INTO upload_history (field1, field2, field3)     VALUES ({0}, {1}, {2})",    ToStringorNull(varField1), ToStringorNull(varField2), ToStringorNull(varField3));

如果你正在使用VS 2008,你甚至可以将其实现为扩展方法。

string insertString = String.Format(    @"INSERT INTO upload_history (field1, field2, field3)     VALUES ({0}, {1}, {2})",    varField1.ToStringorNull, varField2.ToStringorNull, varField3.ToStringorNull);

我会把创建ToStringOrNull函数的任务留给你 - 这并不难 :-)

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