Как мне обойти проблему "" "в sqlite и c #? - PullRequest
6 голосов
/ 25 мая 2009

Я работаю в Microsoft Visual C # 2008 Express с Sqlite.

Я понимаю, что апостроп (') в моем тексте имеет проблемы в запросе. Моя проблема в том, что я думал, что смогу заменить его на \ '. Кажется, он не работает ... Вот пример моего кода:

string myString = "I can't believe it!";
cmd.CommandText = "Insert into myTable (myid,mytext) values (1,'" + myString.Replace("'","\\'") + "');";

Я получаю ошибку: Ошибка SQLite: около "t": синтаксическая ошибка

Я пробовал пару других замен ... как и другой слэш. И я записал свою строку и замененную версию своей строки в консоль, чтобы убедиться, что она выходит правильно.

Какую глупую ошибку я здесь делаю?

Спасибо!

-Adeena

Ответы [ 2 ]

18 голосов
/ 25 мая 2009

Представленное Робертом решение будет работать (то есть, заменив ' на '').

В качестве альтернативы вы можете использовать параметры как:

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();
7 голосов
/ 29 мая 2009

Использование параметров защищает от 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();
  }
}

Sqlite ведет себя подобно Oracle, когда речь заходит о важности использования параметризованных операторов SQL.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...