2009-03-16 4 views
6

Sono in procinto di convertire diverse query che sono state codificate nell'applicazione e create al volo su query parametrizzate. Ho problemi con una sola query particolare, che ha un in clausola:C# Parameterized Query MySQL con clausola `in`

UPDATE TABLE_1 SET STATUS = 4 WHERE ID IN (1, 14, 145, 43); 

Il primo parametro è facile, in quanto è solo un parametro normale:

MySqlCommand m = new MySqlCommand("UPDATE TABLE_1 SET STATUS = ? WHERE ID IN (?);"); 
m.Parameters.Add(new MySqlParameter("", 2)); 

Tuttavia, il secondo parametro è un elenco di numeri interi che rappresentano gli ID delle righe che devono essere aggiornati. Come posso passare un elenco di numeri interi per un singolo parametro? In alternativa, come procederesti nell'impostare questa query in modo da non doverla creare completamente ogni volta che la chiami e impedire attacchi di SQL injection?

+0

duplicati di http://stackoverflow.com/questions/337704/parameterizing-a-sql-in-clause (anche se questo è SQL server, invece di mysql , improbabile che sia davvero diverso però) –

+0

La soluzione offerta lì è stata riconosciuta come incredibilmente lenta, sebbene risponda alla seconda metà della mia domanda. – Elie

+0

Ci sono * molte * soluzioni disponibili lì. La risposta accettata non è la più popolare. –

risposta

4

Si potrebbe costruire la query parametrizzata "on the fly" in base al numero (presumibilmente) variabile di parametri, e iterare che di passarli in

Quindi, qualcosa come:.

List foo; // assuming you have a List of items, in reality, it may be a List<int> or a List<myObject> with an id property, etc. 

StringBuilder query = new StringBuilder("UPDATE TABLE_1 SET STATUS = ? WHERE ID IN (?") 
for(int i = 1; i++; i < foo.Count) 
{ // Bit naive 
    query.Append(", ?"); 
} 

query.Append(");"); 

MySqlCommand m = new MySqlCommand(query.ToString()); 
for(int i = 1; i++; i < foo.Count) 
{ 
    m.Parameters.Add(new MySqlParameter(...)); 
} 
+0

Stavo solo pensando questo. Ma potrei ottenere i vantaggi in termini di prestazioni di avere una query con parametri memorizzati se lo facessi? – Elie

+0

Ado.Net suggerisce le migliori prestazioni creando una nuova connessione, utilizzandola una volta e gettandola via - almeno per altri motori SQL; Dopo tutto, il motore di query potrebbe ottimizzare in base alla stringa di query per riutilizzarli ... –

2

Non è possibile utilizzare i parametri per una clausola IN.

-1

Suggerirei di creare una funzione (presupponendo che mysql supporti le funzioni definite dall'utente) per dividere il parametro a parte per restituire una tabella.

0

Fai scorrere l'elenco di numeri interi ed esegui singoli aggiornamenti.

MSSQL 2008 offre parametri con valori di tabella per evitare questo problema, non sono a conoscenza di alcuna funzionalità simile in MySQL.

+0

Ciò sarebbe incredibilmente inefficiente, considerando che questa query potrebbe, in alcuni casi, avere migliaia di elementi nella clausola IN. – Elie

+0

Non c'è un limite al numero di oggetti che puoi avere in una clausola IN? – Svish

5

Questo non è possibile in MySQL. È possibile creare un numero di parametri richiesto e fare UPDATE ... IN (?,?,?,?). Ciò impedisce attacchi di iniezione (ma richiede comunque di ricostruire la query per ogni numero di parametri).

Un altro modo è passare una stringa separata da virgole e analizzarla.

1

vecchia questione, ma nel caso qualcuno si imbatte in questo tramite Google, ecco quello che io uso:

int status = 4; 
string ids = "1,14,145,43";  

m.Parameters.AddWithValue("@Status", status); 
m.Parameters.AddWithValue("@IDs", ids); 

UPDATE TABLE_1 SET STATUS = @Status WHERE FIND_IN_SET(ID, @IDs) > 0; 

Nota: FIND_IN_SET è una funzione specifica mySQL.

di credito, che è di Cesare: Vedere questa domanda: Add List<int> to a mysql parameter