【问题标题】:How do I get around the "'" problem in sqlite and c#?如何解决 sqlite 和 c# 中的“'”问题?
【发布时间】:2010-10-28 15:14:27
【问题描述】:

我正在使用 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”附近:语法错误

我已经尝试了其他几个替代...就像另一个斜线一样。我将我的字符串和我的字符串的替换版本写到控制台,以确保它正确输出。

我在这里犯了什么愚蠢的错误?

谢谢!

-阿迪娜

【问题讨论】:

    标签: c# string sqlite


    【解决方案1】:

    Robert 提出的解决方案将起作用(即将' 替换为'')。

    您也可以使用以下参数:

    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 用于使用参数。 Robert 的解决方案当然可以,但使用参数也有助于防止 SQL 注入攻击。
    • 所以将输入中的 ' 替换为 '' tho。
    【解决方案2】:

    使用参数可以防止 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。

    【讨论】:

    • 同意。到目前为止,这是更好的答案。
    • 是否有必要在“使用”中获得 conn 时调用 conn.Close() ?有人告诉我这是多余的。
    猜你喜欢
    • 2019-05-23
    • 2020-02-26
    • 2020-01-16
    • 2021-07-23
    • 2016-11-24
    • 2021-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多