2009-05-24 38 views
6

Estoy trabajando en Microsoft Visual C# 2008 Express con Sqlite.¿Cómo soluciono el problema "'" en sqlite y C#?

Entiendo que un apostrope (') en mi texto tiene problemas en una consulta. Mi problema es que pensé que podría reemplazarlo por \ '. No parece estar funcionando ... Aquí está un ejemplo parred abajo de mi código:

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

El error que consigo es: error SQLite: cerca de la "t": error de sintaxis

I He intentado un par de otros reemplazos ... como el otro corte. Y escribí mi cadena y una versión reemplazada de mi cadena en la consola para asegurarme de que saliera bien.

¿Qué error estúpido estoy haciendo aquí?

Gracias!

-Adeena

Respuesta

18

La solución presentada por Robert trabajará (es decir, la sustitución de ' por '').

Alternativamente, puede utilizar parámetros como en:

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 para el uso de parámetros. La solución de Robert funcionará, por supuesto, pero el uso de parámetros también ayudará a proteger contra los ataques de inyección de SQL. –

+0

Así que reemplazará 'en la entrada con' 'tho. – Blindy

7

El uso de parámetros protege contra la inyección de SQL, y hace que los "problemas QO de distancia.

También es mucho más rápido porque sqlite puede reutilizar el plan de ejecución de sentencias cuando usa parámetros. No puede cuando no usas parámetros. En este ejemplo, el uso de un parámetro hace que la acción de inserción masiva sea aproximadamente 3 veces más rápida.

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 se comporta de forma similar a Oracle en lo que respecta a la importancia de utilizar sentencias SQL parametrizadas.

+0

De acuerdo. Esta es la mejor respuesta de lejos. –

+0

¿Es necesario llamar a conn.Close() cuando tienes la conexión en "usar"? Me dijeron que eso era redundante. –

Cuestiones relacionadas