2009-03-16 10 views
6

Ich bin dabei, mehrere Abfragen zu konvertieren, die fest in die Anwendung geschrieben wurden und im Handumdrehen zu parametrisierten Abfragen wurden. Ich habe Probleme mit einer bestimmten Abfrage, die eine in Klausel:C# parametrisierte Abfrage MySQL mit `in` -Klausel

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

Der erste Parameter ist einfach, da es nur ein normaler Parameter:

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

jedoch der zweite Parameter ist ein Liste von Ganzzahlen, die die IDs der Zeilen repräsentieren, die aktualisiert werden müssen. Wie gebe ich eine Liste von ganzen Zahlen für einen einzelnen Parameter ein? Oder wie würden Sie diese Abfrage einrichten, so dass Sie sie nicht jedes Mal neu erstellen müssen, wenn Sie sie aufrufen, und SQL Injection-Angriffe verhindern können?

+0

Duplizieren von http://stackoverflow.com/questions/337704/parameterizing-a-sql-in-clause (obwohl die SQL Server mysql statt ist (wahrscheinlich nicht wirklich anders) –

+0

Die dort angebotene Lösung wurde als unglaublich langsam erkannt, obwohl sie die zweite Hälfte meiner Frage beantwortet. – Elie

+0

Hier werden * viele * Lösungen angeboten. Die angenommene Antwort ist nicht die beliebteste. –

Antwort

4

Sie konnten die parametrisierte Abfrage "on the fly" aufzubauen auf der Grundlage der (vermutlich) variable Anzahl von Parametern, und darüber iterieren sie in passieren

Also, so etwas wie:.

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

Ich habe gerade darüber nachgedacht. Aber würde ich die Leistungsvorteile einer gespeicherten parametrisierten Abfrage erhalten, wenn ich das täte? – Elie

+0

Ado.Net schlägt vor, die beste Leistung zu erzielen, indem man eine neue Verbindung erstellt, sie einmal verwendet und wegwirft - zumindest für andere SQL-Engines; Schließlich könnte die Abfrage-Engine basierend auf der Abfragezeichenfolge optimieren, um sie wiederzuverwenden ... –

2

Sie können keine Parameter für eine IN-Klausel verwenden.

-1

Ich würde vorschlagen, eine Funktion zu erstellen (vorausgesetzt, dass mysql benutzerdefinierte Funktionen unterstützt), um den Parameter auseinander zu brechen, um eine Tabelle zurückzugeben.

0

Runden Sie die Liste der Ganzzahlen ab und führen Sie individuelle Aktualisierungen durch.

MSSQL 2008 bietet Tabellenwertparameter, um dieses Problem zu vermeiden, mir ist keine ähnliche Funktionalität in MySQL bekannt.

+0

Das wäre unglaublich ineffizient, wenn man bedenkt, dass diese Abfrage in einigen Fällen Tausende von Elementen in der IN-Klausel haben könnte. – Elie

+0

Gibt es keine Begrenzung für die Anzahl der Elemente in einer IN-Klausel? – Svish

5

Dies ist in MySQL nicht möglich. Sie können eine erforderliche Anzahl von Parametern erstellen und UPDATE ... IN (?,?,?,?) Ausführen. Dies verhindert Injektionsangriffe (Sie müssen jedoch die Abfrage für jede Parameteranzahl neu erstellen).

Eine andere Möglichkeit besteht darin, eine durch Kommas getrennte Zeichenfolge zu übergeben und zu analysieren.

1

alte Frage, aber im Falle kommt jemand über diese über Google, hier ist was ich benutze:

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; 

Hinweis: FIND_IN_SET ist eine mySQL spezifische Funktion.

Kredit, wem Ehre gebührt: Mit dieser Frage sehen: Add List<int> to a mysql parameter

Verwandte Themen