我正在使用Sqlite在Microsoft Visual C#2008 Express中工作。
据我所知,我的文字中的一个叛逆者(')在查询中存在问题。我的问题是,我认为我可以用\'替换它。它似乎不起作用......这是我的代码的一个例子:
string myString = "I can't believe it!";
cmd.CommandText = "Insert into myTable (myid,mytext) values (1,'" + myString.Replace("'","\\'") + "');";
我得到的错误是: SQLite错误: “t”附近:语法错误
我尝试了其他一些替代品......就像其他的斜线一样。我将我的字符串和我的字符串的替换版本写入控制台,以确保它正确出现。
我在这里犯了什么愚蠢的错误?
谢谢!
-Adeena
答案 0 :(得分:18)
罗伯特提出的解决方案将起作用(即用'
替换''
)。
或者,您可以使用以下参数:
DbCommand cmd = new DbCommand();
DbParameter param = cmd.CreateParameter();
// ...
// more code
// ...
cmd.CommandText = "Insert table (field) values (@param)";
param.ParameterName = "param"
param.DbType = DbType.String;
param.Value = @"This is a sample value with a single quote like this: '";
cmd.Parameters.Add(param);
cmd.ExecuteNonQuery();
答案 1 :(得分:7)
使用参数可以防止sql注入,并使'问题远离。
它也快得多,因为在使用参数时,sqlite可以重用语句的执行计划。当你不使用参数时它不能。在此示例中,使用参数使批量插入操作的速度提高约3倍。
private void TestInsertPerformance() {
const int limit = 100000;
using (SQLiteConnection conn = new SQLiteConnection(@"Data Source=c:\testperf.db")) {
conn.Open();
using (SQLiteCommand comm = new SQLiteCommand()) {
comm.Connection = conn;
comm.CommandText = " create table test (n integer) ";
comm.ExecuteNonQuery();
Stopwatch s = new Stopwatch();
s.Start();
using (SQLiteTransaction tran = conn.BeginTransaction()) {
for (int i = 0; i < limit; i++) {
comm.CommandText = "insert into test values (" + i.ToString() + ")";
comm.ExecuteNonQuery();
}
tran.Commit();
}
s.Stop();
MessageBox.Show("time without parm " + s.ElapsedMilliseconds.ToString());
SQLiteParameter parm = comm.CreateParameter();
comm.CommandText = "insert into test values (?)";
comm.Parameters.Add(parm);
s.Reset();
s.Start();
using (SQLiteTransaction tran = conn.BeginTransaction()) {
for (int i = 0; i < limit; i++) {
parm.Value = i;
comm.ExecuteNonQuery();
}
tran.Commit();
}
s.Stop();
MessageBox.Show("time with parm " + s.ElapsedMilliseconds.ToString());
}
conn.Close();
}
}
当谈到使用参数化sql语句的重要性时,Sqlite的行为与Oracle类似。