Query sql dynamic parametrizzata

Ho un elenco di parole chiave che memorizzo in un elenco.

Per recuperare i record da una tabella, sto usando la seguente query:

sqlBuilder.Append("SELECT name, memberid FROM members WHERE"); StringBuilder sqlBuilder = new StringBuilder(); foreach (string item in keywords) { sqlBuilder.AppendFormat(" LOWER(Name) LIKE '%{0}%' AND", item); } string sql = sqlBuilder.ToString(); 

Come avrai notato, la mia query è vulnerabile a SQL injection, quindi voglio usare i parametri usando SqlCommand (). Ho provato quanto segue ma ancora non funziona:

 foreach (string item in keywords) { sqlBuilder.AppendFormat(" LOWER(Name) LIKE '%' + @searchitem + '%' AND", item); SqlCommand cmd = new SqlCommand(sqlBuilder.ToString()); cmd.Parameters.AddWithValue("@searchitem",item); } 

Dove potrei fare l’errore, o meglio, come dovrei farlo?

Stai facendo alcune cose sbagliate qui:

  • Dai a tutti i tuoi parametri lo stesso nome @searchitem . Quello non funzionerà. I parametri richiedono nomi univoci.
  • Si crea un nuovo SqlCommand per ciascun elemento. Quello non funzionerà. Creare SqlCommand una volta all’inizio del ciclo e quindi impostare CommandText una volta CommandText di creare l’SQL.
  • Il tuo SQL termina con AND , che non è una syntax valida.

Suggerimenti per il miglioramento (non di per sé errati, ma non le migliori pratiche):

  • Come suggerito da Frederik, il modo usuale consiste nel mettere i token % nel parametro, piuttosto che fare una concatenazione di stringhe all’interno di SQL.
  • A meno che non si utilizzi esplicitamente una regola di confronto con distinzione tra maiuscole e minuscole per il proprio database, i confronti non dovrebbero distinguere tra maiuscole e minuscole. Quindi, potresti non aver bisogno di LOWER .

Esempio di codice:

 SqlCommand cmd = new SqlCommand(); StringBuilder sqlBuilder = new StringBuilder(); sqlBuilder.Append("SELECT name, memberid FROM members "); var i = 1; foreach (string item in keywords) { sqlBuilder.Append(i == 1 ? " WHERE " : " AND "); var paramName = "@searchitem" + i.ToString(); sqlBuilder.AppendFormat(" Name LIKE {0} ", paramName); cmd.Parameters.AddWithValue(paramName, "%" + item + "%"); i++; } cmd.CommandText = sqlBuilder.ToString(); 

Non inserire i caratteri jolly nella tua querystring, ma aggiungili al tuo valore-parametro:

 sql = "SELECT name FROM members WHERE Name LIKE @p_name"; ... cmd.Parameters.AddWithValue("@p_name", "%" + item + "%"); 

Quando si aggiungono i caratteri jolly all’interno della stringa di query, il parametro verrà sfuggito, ma i caratteri jolly non lo faranno; ciò comporterà una query che viene inviata al DB che assomiglia a questo:

 SELECT name FROM members WHERE Name LIKE %'somename'% 

che ovviamente non è corretto.

Accanto a ciò, stai creando un SqlCommand in un ciclo che non è necessario. Inoltre, stai creando parametri con un nome non univoco, poiché li stai aggiungendo in un ciclo e il parametro ha sempre lo stesso nome. Devi anche rimuovere l’ultima parola chiave AND, quando esci dal ciclo.