2009-05-24 8 views
6

저는 Sqlite로 Microsoft Visual C# 2008 Express에서 일하고 있습니다.sqlite 및 C#의 " '"문제를 어떻게 해결할 수 있습니까?

내 텍스트의 아포 스트로피 (')에 쿼리에 문제가 있다는 것을 알고 있습니다. 내 문제는 내가 그것을 \ '로 대체 할 수 있다고 생각했기 때문이다.

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

내가 오류는 다음과 같습니다 : SQLite는 오류 : 근처 "t": 구문 오류

I는 여기에 내 코드의 아래 parred 예입니다 ... 작동하지 않는 것 다른 슬래시와 같은 몇 가지 다른 대체품을 시도했습니다. 그리고 필자는 필자의 문자열과 교체 된 버전의 문자열을 콘솔에 출력하여 제대로 나오는지 확인했습니다.

내가 멍청한 오류가 발생하는 이유는 무엇입니까?

감사합니다. 로버트 제시

-Adeena

답변

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(); 
+2

+1 매개 변수 사용. Robert의 솔루션은 물론 작동하지만 매개 변수를 사용하면 SQL 주입 공격으로부터 보호하는 데 도움이됩니다. –

+0

그래서 '입력에서'tho로 바뀝니다. – Blindy

7

는 SQL 주입을 방지하고, '문제를 멀리 QO 있습니다.

sqlite는 매개 변수를 사용할 때 명령문의 실행 계획을 다시 사용할 수 있으므로 훨씬 빠릅니다. 매개 변수를 사용하지 않는 경우에는 사용할 수 없습니다. 이 예제에서 매개 변수를 사용하면 대량 삽입 작업이 약 3 배 더 빠릅니다. 이 매개 변수화 SQL 문을 사용의 중요성에 관해서

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는 오라클과 유사하게 작동합니다.

+0

동의. 이것은 훨씬 더 나은 대답입니다. –

+0

conn.Close()를 호출 할 필요가 있습니까? "사용 중"으로 conn을 얻었습니까? 나는 그것이 불필요하다고 들었다. –

관련 문제