我对SQL,Access和C#没有多少经验,但我找不到解决问题的方法,对于拥有更多专业知识的人来说这应该看起来很简单。
基本上,用户在Winform中填充一些文本框,他可能会插入一些“特殊”字符(至少对于DB字符串是特殊的),例如'
。因此,这些数据通过OleDb
连接传输到数据库中;假设string myString = this.textBox1.Text
是我想要插入到表MY_FIELD
的字段myTable
中的值。
我的首发代码很简单:
OleDbConnection conn = new OleDbConnection(@"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + this.DBstring);
OleDbCommand comm = new OleDbCommand();
comm.CommandText = "INSERT INTO myTable (MY_FIELD) VALUES ('" + myString + "')";
comm.CommandType = CommandType.Text;
comm.Connection = conn;
conn.Open();
comm.ExecuteNonQuery();
conn.Close();
如果myString
类似guns'n'roses
,则上述代码很容易失败,因为comm.CommandText
将是以下字符串值,该值无效SQL:{{1} }。
我显然不是第一个遇到这种问题的新手。所以我通过Stack Overflow搜索了一下,发现了以下thread,其中一个人在命令字符串中插入括号时遇到问题。因此,我试图根据接受的答案调整我的代码:
INSERT INTO myTable(MY_FIELD) VALUES ('guns'n'roses')
但这会引发comm.CommandText = "INSERT INTO myTable (MY_FIELD) VALUES (?)";
comm.Parameters.Add(myString);
InvalidCastException
有没有人可以请我告诉我在Access数据库中插入任何类型的字符串的最佳做法是什么,而不会因为SQL解释器具有“特殊”含义的字符而导致SQL命令失败?
答案 0 :(得分:2)
使用OleDbParameter是正确的。每次要将值传递给数据库引擎时,都应该使用参数。第二次尝试的唯一问题是您没有使用正确的语法来创建命令集并将参数添加到命令集
comm.CommandText = "INSERT INTO myTable (MY_FIELD) VALUES (?)";
comm.Parameters.Add("@name", OleDbType.VarWChar).Value = myString;
当然,如果您的MY_FIELD是文本字段,如果它是数字,那么您需要使用相应的OleDbType枚举。
说我建议将你的代码更改为这个例子
string cmdText = "INSERT INTO myTable (MY_FIELD) VALUES (?)";
using(OleDbConnection conn = new OleDbConnection(....))
using(OleDbCommand comm = new OleDbCommand(cmdText, conn))
{
conn.Open();
comm.Parameters.Add("@name", OleDbType.VarWChar).Value = myString;
comm.ExecuteNonQuery();
}
主要区别在于Using Statement。使用此语法,您可以在完成使用它们释放所使用的任何系统资源后正确关闭和处理您的一次性对象(连接和命令)。在例外的情况下也会发生这种情况
答案 1 :(得分:1)
OleDbParameterCollection的.Add方法有几个重载,而带有单个参数的方法期望该参数是OleDbParameter 对象。
如果要传递参数的字符串 value ,则需要使用接受参数的名称,类型和列宽的重载,即{{3} },然后分配.Value
,如下所示:
comm.Parameters.Add("?", OleDbType.VarWChar, 255).Value = myString;
而且,正如@Steve所说,你应该总是使用参数而不是“动态SQL”(这是你通过将值“粘合”到SQL语句本身而首次尝试的方式)。