将特殊字符(如 ' 或 +)插入 Access 数据库

Inserting special chars (such as ' or +) into an Access database

我在 SQL、Access 或 C# 方面经验不多,但我找不到解决问题的方法,对于具有更多专业知识的人来说应该看起来很简单。

基本上,用户在 Winform 中填写一些文本框,他可能会插入一些 "special" 个字符(至少,对于 DB 字符串而言是特殊的),例如 '。因此,这些数据通过 OleDb 连接传输到数据库中;假设 string myString = this.textBox1.Text 是我想插入到 table myTable.

字段 MY_FIELD 中的值

起始码

我的起始代码很简单:

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: INSERT INTO myTable(MY_FIELD) VALUES ('guns'n'roses').

进一步研究

我显然不是第一个遇到此类问题的新手。因此,我通过 Stack Overflow 进行了一些搜索,发现了以下 thread,其中有人在将括号插入命令字符串时遇到了问题。因此,我尝试根据已接受的答案调整我的代码:

comm.CommandText = "INSERT INTO myTable (MY_FIELD) VALUES (?)";
comm.Parameters.Add(myString);

但这引发了一个 InvalidCastExceptionThe OleDbParameterCollection only accepts non-null OleDbParameter type objects, not String objects.

任何人都可以告诉我将任何类型的字符串插入 Access 数据库而不会使 SQL 命令失败的最佳做法是什么,因为对 [=] 具有 "special" 含义的字符44=]翻译?

您为此使用 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。使用此语法,您的一次性对象(连接和命令)将在您完成使用它们后正确关闭和处理,释放所使用的任何系统资源。这也会发生在异常的情况下

OleDbParameterCollection 的 .Add 方法有多个重载,具有单个参数的方法期望该参数是 OleDbParameter object

如果要传递参数的字符串 value,则需要使用接受参数的名称、类型和列宽的重载,即, this one, 然后赋值 .Value, 像这样:

comm.Parameters.Add("?", OleDbType.VarWChar, 255).Value = myString;

而且,正如@Steve 所说,您应该总是 使用参数而不是"dynamic SQL"(这是您第一次尝试 "gluing" SQL 语句本身的值)。