2016-03-31 8 views
0

Wir müssen verschiedene Spalten in 3 verschiedenen Tabellen über ein Eingabeformular aktualisieren. Das meiste ist funktional, aber wenn wir versuchen, die anderen 2 Tabellen, die verbunden wurden (Herausgeber und Kategorie), zu aktualisieren, aktualisiert es diesen Datensatz und jeden anderen Datensatz mit der gleichen Eingabe.SQL Update über 3 Tabellen - Where Klausel Problem (?)

(zum Beispiel, wenn wir das Genre aus Metall Jazz ändern dann alles Metall CD wird auch zu Jazz aus)

Unten ist der Code, den wir haben für das Update so weit.

$sql = "UPDATE nmc_cd, nmc_category, nmc_publisher 
SET CDTitle ='$title', CDYear = '$year', nmc_publisher.pubID = '$publisherID', nmc_category.catID = '$categoryID', CDPrice = '$price', pubName ='$pubName', catDesc='$catDesc' 
WHERE CDID = $id 
AND nmc_category.catID = nmc_cd.catID 
AND nmc_publisher.pubID = nmc_cd.pubID"; 

Ich bin relativ neu auf dieser Seite also bitte, wenn etwas wie Code, Namen von Variablen/Funktionen usw. benötigt wird, bitte sagen, und ich werde meinen Beitrag oder eine Antwort bearbeiten.

Vielen Dank im Voraus!

+1

Sie können es nicht in 1 Anweisung tun, Sie müssen es in 1 Update-Anweisung für jede Tabelle teilen, die Sie aktualisieren möchten. Am besten Sie erstellen eine Transaktion und bestätigen sie nach allen 3 Updates. Sie könnten auch einen gespeicherten Prozess schreiben und die Anweisungen dort ausführen (wiederum innerhalb einer Transaktion). – Igor

+0

Mögliches Duplikat von [Wie Aktualisieren von zwei Tabellen in einer Anweisung in SQL Server 2005?] (Http://stackoverflow.com/questions/2044467/how-to-update-two-tables-in-one-statement-in- sql-server-2005) – Igor

+1

Dies fällt wahrscheinlich unter die Domäne von DBMS-spezifischen Macken, anstatt reines SQL zu sein. Bitte geben Sie Ihr Ziel-DBMS an und wir können konkreter werden, wenn dies in einer Abfrage möglich ist oder nicht. Mit reinem SQL ist es wahrscheinlich nicht. – apokryfos

Antwort

0

Ein paar Empfehlungen.

1)alle Spaltenverweise in SQL-Anweisung qualifizieren, die mehr als eine Tabelle verweist, auch wenn die Spalte Verweise auf MySQL nicht eindeutig sind. (Es sollte auch ein kurzer Alias ​​für jede Tabelle verwendet werden.) Mehrere Gründe dafür, aber eine große ist, dass ein menschlicher Leser wissen kann, in welcher Tabelle sich jede referenzierte Spalte befindet.

2) Graben Sie die alte Schule Komma Operator für Join-Operationen, und verwenden Sie das Schlüsselwort JOIN. Verschieben Sie außerdem die Join-Prädikate aus der WHERE-Klausel in die entsprechende ON-Klausel.

3) für ein Multitable zu aktualisieren, schreiben zunächst eine SELECT Aussage, dass die Arbeit und getestet, und dann, dass

4) vermeiden SQL-Injection-Schwachstellen zu einer UPDATE Anweisung konvertieren. Das bevorzugte Muster besteht darin, vorbereitete Anweisungen mit Bind-Platzhaltern zu verwenden. Oder (weniger optimal) müssen alle potenziell unsicheren Werte, die im SQL-Text enthalten sind, ordnungsgemäß maskiert werden.


Ignorieren SQL-Injection-Schwachstellen (unter der Annahme, dass der Inhalt der Variablen bereits richtig übersetzt worden) ...

Ich würde zuerst eine SELECT-Anweisung schreiben, die die aktuellen Werte der Spalten zurückgibt, wir sind Sie planen die Aktualisierung zusammen mit den neuen Werten, die wir diesen Spalten zuweisen möchten. Zum Beispiel:

SELECT cd.cdtitle  AS old_cd_cdtitle 
     , '$title'  AS new_cd_cdtitle 

     , cd.cdyear  AS old_cdyear 
     , '$year'   AS new_cdyear 

     , pub.pubid  AS old_pub_pubid 
     , '$publisherID' AS new_pub_pubid 

     , cat.catid  AS old_cat_catid 
     , '$categoryID' AS new_cat_catid 

     , cd.cdprice  AS old_cd_cdprice 
     , '$price'  AS new_cd_cdprice 

     , pub.pubName  AS old_pub_pubname 
     , '$pubName'  AS new_pub_pubname 

     , cat.catDesc  AS old_cat_catdesc 
     , '$catDesc'  AS new_cat_catdesc 

    FROM nmc_cd cd 
    JOIN nmc_category cat 
    ON cat.catID = cd.catid 
    JOIN nmc_publisher pub 
    ON pub.pubID = cd.pubid 
    WHERE cd.cdid = $id 

(Das ist wirklich nur eine Vermutung, ich bin nicht sicher, was Sie eigentlich erreichen wollen.)

Es ist wirklich seltsam scheint einen neuen Wert der catid Spalte zuweisen, wenn das in einem Join-Prädikat referenziert wird. Um die Beziehung zwischen den Zeilen in cd und cat beizubehalten, müsste die Spalte catid in beiden Tabellen aktualisiert werden, es sei denn, wir sind auf eine ON UPDATE CASCADE Regel angewiesen, die Änderung zu propagieren.

Ohne zu verstehen, was diese Anweisung zu erreichen versucht, ist es nicht möglich, eine bestimmte Aussage zu empfehlen.

In Bezug auf die SELECT in eine UPDATE Anweisung Umwandlung, ersetzen Sie die SELECT ... FROM mit dem Schlüsselwort UPDATE.

Und vor der WHERE Klausel, fügen Sie eine SET Anweisung hinzu. Nimmt man die Expresssions für old_cd_cdyear und new_cd_cdyear aus der SELECT-Liste, konvertieren, dass in einer SET-Klausel wie folgt aus:

SET cd.cdyear  = '$year' 

Nachfolgende Zuweisungen, ein Komma anstelle des SET-Schlüsselwort verwenden, z.B.

 , cd.cdprice  = '$price' 
+0

Die "Regeln" zum Konvertieren einer SELECT-Anweisung in ein UPDATE richten sich an MySQL. Andere RDBMS haben unterschiedliche Syntax für das Multitable-Update. Ohne eine Spezifikation dessen, was die Anweisung erreichen soll (Tabelleninhalte sowohl vor als auch nach der Änderung, einschließlich Zeilen, die nicht geändert werden sollen), ist es nicht wirklich möglich, eine geeignete Syntax dafür zu empfehlen.) Ohne eine Spezifikation " einfach werfen "versuchen Sie es" an der Wand zu sehen, was klebt. Es gibt viele Dinge, die wir ausprobieren können, aber ohne zu wissen, was wir eigentlich erreichen wollen, wie würden wir wissen, ob wir es "bekommen"? – spencer7593

+0

Wir haben uns bereits den Tabellen angeschlossen. Alles, was wir zu tun versuchen, ist eine Update-Anweisung, um die Informationen in den 3 Tabellen zu aktualisieren, wenn Informationen vom Benutzer auf dem Website-Formular eingegeben werden. Dies ist unser zu verbinden, dass wir derzeit haben '$ sql =„SELECT * \t VON nmc_cd \t INNER nmc_category \t ON nmc_category.catID = nmc_cd.catID \t INNER JOIN nmc_publisher \t ON JOIN nmc_publisher.pubID = nmc_cd.pubID \t WHERE CDID = $ ID ORDER BY CDTitle ";" entschuldigt sich für die Formatierung. – spesh

+0

@spesh: * Welche * Spalten in * welchen * Zeilen von * welchen * Tabellen müssen Sie aktualisieren? Die Angabe "Informationen in den 3 Tabellen aktualisieren" ist vage ungenau. Wie ich in meiner Antwort angemerkt habe, wenn Sie Fremdschlüssel haben, die 'cat.catid' mit einer ON UPDATE CASCADE referenzieren, dann werden, wenn Sie' cat.catid' einen neuen Wert zuweisen, auch jene Fremdschlüsselspalten verwendet, die auf den alten Wert verweisen verändert sein. Die Beziehung zwischen den Zeilen wird beibehalten. Wenn Sie auch 'cat.catname' einen neuen Wert zuweisen, verweisen alle diese Zeilen (die sich auf' cat.catid' beziehen) ebenfalls auf den neuen 'catname'. – spencer7593