Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   SQL Update alle Einträge (https://www.delphipraxis.net/152394-sql-update-alle-eintraege.html)

ibp 21. Jun 2010 12:42

Datenbank: Interbase • Version: 6.5 • Zugriff über: SQL

SQL Update alle Einträge
 
Hallo,

gibt es eine Möglichkeit mit einer UPDATE Anweisung alle Datensätze zu ändern ABER mit unterschiedlichen Werten für die einzelnen Datensätze?

Struktur:
Tab1 (pkey,reckey,sortstr)
Tab2 (pkey,f1,f2,...fn)

Tab1.reckey=Tab2.pkey

Es kann mehrere Datensätze in Tab1 geben die den gleichen reckey haben!

Was gemacht werden soll: Tab1.sortstr soll aktualisiert werden. Dabei entspricht Tab1.sortstr=concat(tab2.f5+tab2.f1+...)

Wie bekomme ich das mit einem SQL-Statement hin ohne alle Datensätze in Tab2 durchlaufen zu müssen?

Hat jemand einen Tipp?

mkinzler 21. Jun 2010 12:44

AW: SQL Update alle Einträge
 
Und wie unterscheiden sich die Werte? Ist der neue Wert berechenbar?

ibp 21. Jun 2010 12:51

AW: SQL Update alle Einträge
 
Zitat:

Zitat von mkinzler (Beitrag 1030587)
Und wie unterscheiden sich die Werte? Ist der neue Wert berechenbar?

Nein die neuen Werte sind nicht berechenbar. Es werden die Felder nach einer bestimmten Definition aus Tab2 zusammengefügt.

mkinzler 21. Jun 2010 12:53

AW: SQL Update alle Einträge
 
Dann sind sie ja "berechenbar/ermittelbar"

DeddyH 21. Jun 2010 12:53

AW: SQL Update alle Einträge
 
Falls ich Dich richtig verstanden habe kannst Du es mal so versuchen:
SQL-Code:
UPDATE Tab1
SET sortstr = (
  SELECT Tab2.f5 || Tab2.f1 || ...
  FROM Tab2
  WHERE Tab2.pkey = Tab1.reckey)

ibp 21. Jun 2010 13:08

AW: SQL Update alle Einträge
 
also mit
Code:
select (tab2.f2||tab3.fx ...)
from tab1
left outer join tab2 an (tab1.reckey=tab2.pkey)
erhalte ich die richtige Ergebnismenge aber leider meckert interbase beim update mit "multiple rows in singleton select"

mkinzler 21. Jun 2010 13:09

AW: SQL Update alle Einträge
 
Der Subquery liefert mehrere Ergebniszeilen; du musst diesen so anpassen, dass genau ein Ergebnis rauskommt.

DeddyH 21. Jun 2010 13:13

AW: SQL Update alle Einträge
 
Dann habe ich die Master-Detail-Beziehung doch falsch verstanden (oder sie war falsch geschildert).

ibp 21. Jun 2010 13:16

AW: SQL Update alle Einträge
 
Zitat:

Zitat von mkinzler (Beitrag 1030607)
Der Subquery liefert mehrere Ergebniszeilen; du musst diesen so anpassen, dass genau ein Ergebnis rauskommt.

ja aber genau das will ich ja nicht, ich will gleichzeitig alle Datensätze in Tab1 updaten aber eben nicht mit einem Wert sondern mit verschiedenen, die sind abhängig von den verknüpften Datensätzen...

DeddyH 21. Jun 2010 13:21

AW: SQL Update alle Einträge
 
Er meint je zu aktualisierendem Datensatz ein Datensatz aus der Subquery. Im Moment kommen in Letzterer noch mehrere, da musst Du die Kriterien anpassen, damit nur der eine passende kommt.

ibp 21. Jun 2010 13:23

AW: SQL Update alle Einträge
 
Zitat:

Zitat von DeddyH (Beitrag 1030619)
Er meint je zu aktualisierendem Datensatz ein Datensatz aus der Subquery. Im Moment kommen in Letzterer noch mehrere, da musst Du die Kriterien anpassen, damit nur der eine passende kommt.

ja aber es soll ja nicht einer sein, sondern alle die der Verknüpfung etsprechen!

DeddyH 21. Jun 2010 13:24

AW: SQL Update alle Einträge
 
Ja, die Du updaten willst. Das geht mit der Subquery aber nur, wenn diese genau einen Datensatz liefert.

mkinzler 21. Jun 2010 13:31

AW: SQL Update alle Einträge
 
Der SubQuery wird ja einmal pro Datensatz ausgeführt, und muss dann das Ergebnis für diesen Datensatz liefern

ibp 21. Jun 2010 13:33

AW: SQL Update alle Einträge
 
Zitat:

Zitat von DeddyH (Beitrag 1030624)
Ja, die Du updaten willst. Das geht mit der Subquery aber nur, wenn diese genau einen Datensatz liefert.

dann geht es nicht was ich will...muss ich mich wohl doch in psql einarbeiten....

ibp 21. Jun 2010 13:37

AW: SQL Update alle Einträge
 
Zitat:

Zitat von mkinzler (Beitrag 1030630)
Der SubQuery wird ja einmal pro Datensatz ausgeführt, und muss dann das Ergebnis für diesen Datensatz liefern

wie komme ich dann an den key ran für den Datensatz für den gerade das update läuft?

mkinzler 21. Jun 2010 13:44

AW: SQL Update alle Einträge
 
Z.B. wenn du ein Alias setzt
SQL-Code:
UPDATE Tab1 t
SET t.sortstr = (
  SELECT t2.<Feld aus Tab2>
  FROM Tab2 t2
  WHERE t2.pkey = t.reckey);

DeddyH 21. Jun 2010 13:49

AW: SQL Update alle Einträge
 
Und das ist jetzt fast genau wieder mein Statement aus #5, nur mit Alias und umgedrehten Tabellen :mrgreen:

ibp 21. Jun 2010 14:42

AW: SQL Update alle Einträge
 
Zitat:

Zitat von mkinzler (Beitrag 1030641)
Z.B. wenn du ein Alias setzt
SQL-Code:
UPDATE Tab1 t
SET t.sortstr = (
  SELECT t2.<Feld aus Tab2>
  FROM Tab2 t2
  WHERE t2.pkey = t.reckey);

:wall:

ja danke so klappt es....

ibp 21. Jun 2010 16:32

AW: SQL Update alle Einträge
 
das ist leider zu langsam.....

Gibt es eine Möglichkeit die ganze Ergebnismenge des Select-Statements auf einmal in eine vor selektierte Zieltabelle zu schreiben?

alex517 21. Jun 2010 18:35

AW: SQL Update alle Einträge
 
Hi,

ab Firebird 2.1 gibt es dafür
SQL-Code:
MERGE INTO ..
aber ob Interbase 6.5 das kann weis ich nicht.

alex

Edit:
[OffTopic]
kann mir jemand sagen wo ich die SQL-Tags finde?
[/OffTopic]

DeddyH 21. Jun 2010 18:39

AW: SQL Update alle Einträge
 
[ code=SQL ] (ohne Leerzeichen natürlich)

alex517 21. Jun 2010 19:11

AW: SQL Update alle Einträge
 
Zitat:

Zitat von DeddyH (Beitrag 1030728)
[ code=SQL ] (ohne Leerzeichen natürlich)

Danke.
Aber im Moment stelle ich mich noch zu blöd an (siehe #20), aber vllt. lern ich's ja noch.

mkinzler 21. Jun 2010 19:18

AW: SQL Update alle Einträge
 
SQL-Code:
MERGE
gab es nur in der alpha
Und wurde später durch
SQL-Code:
Update or Insert
ersetzt

SQL-Code:
Update Or Insert into <Tabelle> (<Feldliste>)
values ( <Werteliste> )
matching (<Feldliste übereinstimmnde Felder>);
Der SQL-Tag ist eine Erweiterung des Code-Tags; diesen einfach um =SQL erweitern

alex517 21. Jun 2010 20:25

AW: SQL Update alle Einträge
 
Zitat:

Zitat von mkinzler (Beitrag 1030755)
SQL-Code:
MERGE
gab es nur in der alpha
Und wurde später durch
SQL-Code:
Update or Insert
ersetzt

allerdings ist in Firebird das
SQL-Code:
MERGE INTO..
um einiges mächtiger als das
SQL-Code:
Update or Insert
.
wobei beide ihre Berechtigung haben. Aber ich glaube das ist auch schon Off Topic


Zitat:

Zitat von mkinzler
Der SQL-Tag ist eine Erweiterung des Code-Tags; diesen einfach um =SQL erweitern

Mich wunderte nur, warum das "SQL-Code:" bei manchen erscheint, bei mir aber nicht:?
Aber jetzt hab ich's begriffen.

mkinzler 21. Jun 2010 20:31

AW: SQL Update alle Einträge
 
Und was war am
SQL-Code:
MERGE
mächtiger?

alex517 21. Jun 2010 21:32

AW: SQL Update alle Einträge
 
Zitat:

Zitat von mkinzler (Beitrag 1030777)
Und was war am
SQL-Code:
MERGE
mächtiger?

IST!:-D
Bsp. aus der Firebird.Docs:
SQL-Code:
      MERGE
         INTO customers c
         USING (SELECT * FROM customers_delta WHERE id > 10) cd
         ON (c.id = cd.id)
         WHEN MATCHED THEN
            UPDATE SET name = cd.name
         WHEN NOT MATCHED THEN
            INSERT (id, name)
               VALUES (cd.id, cd.name)
Beim "UPDATE OR INSERT" werden IMMER entwerder INSERT oder UPDATE ausgeführt.
Dabei werden beim INSERT und UPDATE die GLEICHEN Felder eingefügt/geändert.

Beim Merge hat man die Möglichkeit beim Update andere Felder als beim Insert zu setzen. Und man kann eine von beiden Operationen wegzulassen.

Um wieder zu Thema "SQL Update alle Einträge" zurückzukehren:
In diesem Fall, es fände nur der
SQL-Code:
..WHEN MATCHED THEN UPDATE SET ..
-Zweig
Verwendung,
SQL-Code:
..WHEN NOT MATCHED THEN INSERT ..
würde man weglassen.

Ein Geschwindigkeitsvorteil gegenüber einem einfachen "UPDATE .. SET = (Select.. From..)"
ergibt sich wenn mehrer Felder der Zieltabelle aus gleichzeitig geändert werden.

SQL-Code:
      
  MERGE INTO customers c
   USING (SELECT * FROM customers_delta WHERE id > 10) cd
   ON (c.id = cd.id)
   WHEN MATCHED THEN
     UPDATE SET
       name = cd.name,
       FeldX = cd.ZZ,
       FeldY = cd.TTT;


Alle Zeitangaben in WEZ +1. Es ist jetzt 17:28 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz