2009-05-14 24 views
7

Nehmen wir an, eine gespeicherte Prozedur SetCustomerName hat einen Eingabeparameter Name, und ich habe eine Tabelle Kunden mit Spalte Name. Also in meiner gespeicherten Prozedur möchte ich den Namen des Kunden festlegen. Wenn ichMySQL: Wenn der Name der Stored Procedure der Name der Tabellenspalte ist

UPDATE customers SET Name = Name;

schreiben, ist dies falsch, und ich sehe zwei andere Möglichkeiten:

UPDATE customers SET Name = `Name`; 
UPDATE customers SET customers.Name = Name;

Zuerst arbeitet man, aber ich fand nicht in der Dokumentation, die ich Parameter innerhalb `Zeichen wickeln können. Oder habe ich es in der Dokumentation vermisst (Link wird in diesem Fall geschätzt).

Welche anderen Möglichkeiten gibt es und wie sieht der Standard für einen solchen Fall aus? Das Umbenennen des Eingabeparameters ist nicht gut für mich (weil ich automatische objekt-relationale Zuordnung habe, wenn Sie wissen, was ich meine).

UPDATE:

So gibt es einen Link zu Backticks (http://dev.mysql.com/doc/refman/5.0/en/identifiers.html), aber es ist nicht tief genug erklärt, wie sie verwenden (wie sie mit den Parametern und Spaltennamen verwenden).

Und es ist eine sehr seltsame Sache (zumindest für mich): Sie können Backticks oder so verwenden:

UPDATE customers SET Name = `Name`; 
//or 
UPDATE customers SET `Name` = Name; 
//or even 
UPDATE customers SET `Name` = `Name`;

und sie alle arbeiten absolut die gleiche Weise.

Findest du das nicht seltsam? Wird dieses seltsame Verhalten irgendwo erklärt?

Antwort

4

Ich denke, dass Ihr erstes Beispiel ist aufgerufen werden. Wenn Sie versuchen, die Spalte „Name“ auf „Name“ Eingabeparameter einstellen, glaube ich es sein sollte:

UPDATE customers SET `Name` = Name; 

Und für das zweite Beispiel, Sie Tabellen-Aliases die gleiche Weise einstellen, die Sie tun in allen anderen Aussagen:

UPDATE customers AS c SET c.Name = Name; 
0

oder verwenden Sie so etwas wie das:

BEGIN 
set @m_query = concat('update users set ',column,' = \'', value,'\' where id = ',user); 

prepare stmt from @m_query; 
execute stmt; 

END 

Spalte & Wert sind TEXT Benutzer sind INT

+1

** Tun Sie das nicht! ** Möchten Sie das SQL wirklich mit String-Verkettung konstruieren? Was ist mit SQL-Injektion? – ADTC

+0

@ADTC, machst du Witze? Um diese gespeicherte Prozedur auszuführen, müssen Sie sich bereits im SQL-Subsystem befinden. Daher können Sie fast jede beliebige Abfrage ausführen. PLUS das ist eine vorbereitete Aussage. Einer der Hauptvorteile von vorbereiteten Anweisungen besteht darin, dass sie die SQL-Injektion verhindern. –

+0

Wenn Sie Strings verketten, um eine Aussage zu treffen, dann "vorbereiten" Sie (ohne irgendwelche Parameter), es ist keine vorbereitete Aussage, es ist nur eine Aussage, die vorgibt, vorbereitet zu sein. – ADTC

14

Der einfachste Weg, um zwischen Ihrem Parameter und der Spalte zu unterscheiden (wenn beide Namen gleich sind), ist das Hinzufügen eines Tabellennamens in Ihrem Spaltennamen.

UPDATE customers SET customers.Name = Name; 

Auch können Sie auch Datenbank-Präfix wie

UPDATE yourdb.customers SET yourdb.customers.Name = Name; 

Durch das Hinzufügen Datenbank Name Sie Aktion auf mehr als 1 Datenbank von einzelnen Speicher Verfahren ausführen können.

+1

Dies sollte als die Antwort markiert werden, Danke. – ykh