SQL 2000 Tabellen vergleichen updaten

hallo zusammen,

ich habe 2 Tabellen die ich miteinander vergleichen und eine mit neuen Werten aus der anderen updaten möchte.

ich habe folgende zwei SQL Scripts probiert aber beide bringen mir die selbe Fehlermeldung:
1.
update artikel set artikel.maxfm = (select atf.maxfm from artikel_tmp_fm as atf join artikel as a on (a.artikel=atf.artikel))
2.
set artikel.maxfm = (select artikel_tmp_fm.maxfm from artikel_tmp_fm where artikel_tmp_fm.artikel = artikel.artikel)

Fehlermeldung: Die Unterabfrage gab mehr als einen Wert zurück. Das ist ungültig, wenn die Unterabfrage auf =, !=, , >= folgt oder als Ausdruck verwendet wird.
Die Anweisung wurde beendet.

wo ist mein Fehler?

vielen Dank

mfg

Daniel

unter 2. fehlt natürlich „update aritkel“ zuvor

Hi,

das Problem dürfte wohl sein, dass Du eine 1:N-Beziehung hast - sprich für einen Artikel in der Tabelle „Artikel“ gibt es 1 _oder_ mehrere Einträge in der Tabelle artikel_tmp_fm. Nun weiss das Update natürlich nicht welchen der zurückgelieferten Werte er nehmen soll.

Der Sub-Select innerhalb eines Updates muss einen eindeutigen Wert zurückbringen. Dies erreichst Du indem Du:

  1. den Join überprüfst und ggfls so eindeutig machst, dass der Subselect nur 1 Zeile zurückliefert/zurückliefern kann
  2. Du eine mathematische Funktion einsätzt wie z.B. MAX, MIN also SELECT MAX(atf.maxfm) FROM …
  3. Du die Zeilenanzahl einschränkst als Zusatzbedingung im Sub-Select mit Hilfe von "AND ROWNUM
    SELECT *
    FROM artikel a
    ,artikel_tmp_fm b
    WHERE a.artikel=atf.artikel
    AND a.artikel = --Hier ein Dir bekannter Schlüssel hin

Dann kannst Du die Zeilen Dir ansehen. Findest Du nicht direkt einen Artikel mit 2 Zeilen kann man auch sowas machen um die ID herauszubekommen (funktioniert zumindest bei Oracle):

SELECT a.artikel, atf.artikel, COUNT(1)
FROM artikel a
,artikel_tmp_fm b
WHERE a.artikel=atf.artikel
GROUP BY a.artikel, atf.artikel
HAVING COUNT(1) > 1 --> kann man auch bei einer überschaubaren Menge weglassen

Gruß
Andreas

hi nochmal,

danke für den Tipp es waren tatsächlich doppelte Artikel in der Tabelle habe sie nun gelöscht und dann nochmal den update Befehl ausgeführt.

-------------------------------------------------------------------
update artikelbew
 set artikelbew.invpreis = 
 (select importtabelle.invpreis 
 from importtabelle 
 where artikelbew.artikel = importtabelle.artikel)
-------------------------------------------------------------------

er hat mir damit zwar alle Werte richtig abgeglichen, allerdings enthält die artikelbew Tabelle mehr invpreise und somit auch Artikel als die Importtabelle, nun hat er mir alle Werte die er in der Importtabelle nicht finden konnte in der Artikelbew Tabelle auf NULL gesetzt und damit vorhandenen invpreise gelöscht!

Wie muss ich mein SQL Script erweitern das das nicht passiert?

gruß

Daniel

Jo,

jetzt wo ich es mir nochmal durchlese ist es auch klar das er nicht gefundene Artikel auf NULL setzt.

Auch hier führen wieder mehrere Wege nach Rom …

z.B. :

update artikelbew
 set artikelbew.invpreis =
 NVL((select importtabelle.invpreis
 from importtabelle
 where artikelbew.artikel =
importtabelle.artikel),artikelbew.invpreis)

Nicht getestet könnte aber funktionieren oder vielleicht eleganter:

update artikelbew
 set artikelbew.invpreis =
 (select importtabelle.invpreis
 from importtabelle
 where artikelbew.artikel =
importtabelle.artikel)
WHERE EXISTS (select 1
 from importtabelle
 where artikelbew.artikel =
importtabelle.artikel)

Gruß
Andreas

super vielen Dank das hat funktioniert

hättest du eventl. noch Zeit mir kurz zu erläutern wie das ausklammern mit where exist und vorallem select 1 funktioniert bzw. was die befehle da machen…

Gruß

Daniel

Exist liefert true, wenn der Subselect wenigstens eine Zeile zurückliefert. Es ist völlig egal was in der Zeile drin steht, daher kann man einfach eine 1 selectieren (selbst ‚select null‘ sollte den selben Effekt haben)

Jens

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

danke für die Erklärung, habs verstanden…

Gruß

Daniel