Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi SQL: JOIN und UPDATE (https://www.delphipraxis.net/131804-sql-join-und-update.html)

ts-d 31. Mär 2009 10:56

Datenbank: Paradox • Version: 1 • Zugriff über: DB-Explorer oder Delphi7-Programmierung

SQL: JOIN und UPDATE
 
Hallo,

in Access habe ich eine Aktualisierungsabfrage zusammengebastelt - in Delphi bzw. im SQL-Fenster des SQL-Explorers (Delphi 7) klappt das nicht:

UPDATE [Auftragpos Paradox] INNER JOIN [Z2_Rabatte pro Hauptposition] ON ([Auftragpos Paradox].pos_h = [Z2_Rabatte pro Hauptposition].pos_h) AND ([Auftragpos Paradox].Auftrnum = [Z2_Rabatte pro Hauptposition].Auftrnum) SET [Auftragpos Paradox].RABATTSATZ = [Z2_Rabatte pro Hauptposition].[RABATTSATZ];

Erklärung:
1. Tabelle heißt Auftragpos und hat mehr Datensätze als die 2. Tabelle Rabatte

Beide Tabellen haben das Feld "RABATTSATZ"

Nun sollen die Werte von Tabelle Rabatte in das identische Feld der Tabelle Auftragpos kopiert werden.

Bedingung: Auftragsnummer (Auftrnum) und Hauptposition (pos_h) sind identisch.



Ein Artikel ist unter "SQL: Update aus zweiter Liste" vorhanden.
Aber der löst das Problem nicht. Nach dem Lösungsvorschlag hieße meine Syntax:
UPDATE 'Auftragpos.db' as a LEFT OUTER JOIN 'Rabatte.db' as o ON a.pos_h = o.pos_h AND a.Auftrnum = o.Auftrnum SET a.RABATTSATZ = o.RABATTSATZ

Fehlermeldung des SQL-Explorers: Invalid use of keyword, Token: LEFT !?



Vielleicht kennt ja jemand noch einen einfacheren Weg, z. B. mit Batch-Move oder Masterfield.
Jedenfalls müssen die Werte am Schluss in der Tabelle Auftragpos verfügbar sein.


vg
Thomas

mkinzler 31. Mär 2009 11:51

Re: SQL: JOIN und UPDATE
 
Es fehlt das select. Versuch mal
SQL-Code:
UPDATE [Auftragpos Paradox] SELECT JOIN [Z2_Rabatte pro Hauptposition] ON ([Auftragpos Paradox].pos_h = [Z2_Rabatte pro Hauptposition].pos_h) AND ([Auftragpos Paradox].Auftrnum = [Z2_Rabatte pro Hauptposition].Auftrnum) SET [Auftragpos Paradox].RABATTSATZ = [Z2_Rabatte pro Hauptposition].[RABATTSATZ];

ts-d 31. Mär 2009 12:05

Re: SQL: JOIN und UPDATE
 
Bei einem UPDATE-Befehl brauche ich doch kein SELECT.

Auf den Delphi-Pages habe ich noch die Lösung gefunden:

update 'Auftragpos.db' a, 'Rabatte.db' o set a.RABATTSATZ = o.RABATTSATZ where a.pos_h = o.pos_h AND a.Auftrnum = o.Auftrnum

Aber da meldet der SQL-Explorer: Token ,
Er mag das KOmma zwischen den beiden Tabellen nicht.

joachimd 31. Mär 2009 12:16

Re: SQL: JOIN und UPDATE
 
Zitat:

Zitat von ts-d
Bei einem UPDATE-Befehl brauche ich doch kein SELECT.

Auf den Delphi-Pages habe ich noch die Lösung gefunden:

update 'Auftragpos.db' a, 'Rabatte.db' o set a.RABATTSATZ = o.RABATTSATZ where a.pos_h = o.pos_h AND a.Auftrnum = o.Auftrnum

Aber da meldet der SQL-Explorer: Token ,
Er mag das KOmma zwischen den beiden Tabellen nicht.

Du darfst auch nur eine Tabelle updaten. Von MS SQL gibt es auch die erweiterte Syntax mit UPDATE FROM (unterstützt u.a. auch vom ADS).
SQL-Code:
update a set F2=b.F2 FROM TabelleA a
  INNER JOIN TabelleB b ON a.F1=b.F1
bzw.
SQL-Code:
update TabelleA set F2=b.F2 FROM TabelleB b
  WHERE TabelleA.F1=b.F1
Diese sind aber nicht ANSI-konform und daher sehr spezifisch!
Lt ANSI müsste es in etwa so gehen:
SQL-Code:
update TabelleA set F2=(select F2 from TabelleB b where b.F1=TabelleA.F1)

Bernhard Geyer 31. Mär 2009 12:31

Re: SQL: JOIN und UPDATE
 
Diverse DBMS unterstützen solche Updates. Aber wie sprechen hier von Paradox und BDE. Es würde mich mehr als wundern wenn sowas hier unterstützt wird.

ts-d 31. Mär 2009 13:14

Re: SQL: JOIN und UPDATE
 
... meine ich auch fast,

bei den letzten Vorschlägen kommt nämlich die Fehlermeldung Fehler bei FROM
und "Single row subquery produced more than one row."

Gibt's denn eine andere Lösung für das Problem?

Bernhard Geyer 31. Mär 2009 13:23

Re: SQL: JOIN und UPDATE
 
Zitat:

Zitat von ts-d
Gibt's denn eine andere Lösung für das Problem?

Ja. "Händisches" Update. Lass dir alle Datensätze per SELECT geben und schreib dann einzelne Update-Statements oder geh mit einer TTable-Komponente und Find durch die Datensätze durch und aktualisiere sie so. Dauert zwar, aber bei so einer alten DB darf man froh sein das sie bei zu vielen aktionen nicht kaputt geht.

ts-d 31. Mär 2009 13:28

Re: SQL: JOIN und UPDATE
 
Danke - schön umständlich, aber immerhin eine Lösung.

vg
Thomas

joachimd 31. Mär 2009 15:21

Re: SQL: JOIN und UPDATE
 
Zitat:

Zitat von ts-d
"Single row subquery produced more than one row."

Du hast mindestens eine Dublette drin! Damit kann keiner umgehen, denn es ist nicht klar, welcher Datensatz als Quelle herhalten soll.

mschaefer 31. Mär 2009 17:01

Re: SQL: JOIN und UPDATE
 
Zitat:

Zitat von ts-d
Danke - schön umständlich, aber immerhin eine Lösung.

BDE - Paradox kann es definitiv nicht anders. // Martin

p80286 31. Mär 2009 17:56

Re: SQL: JOIN und UPDATE
 
Zitat:

Zitat von ts-d
Danke - schön umständlich, aber immerhin eine Lösung.

mach doch etwas in dem Stil:
SQL-Code:
select 'UPDATE tabelle1 SET tabelle1.feld1='||tabelle2.wert||' WHERE tabelle1.satznr='||xxxxx
from ......
Du läßt Dir also den Update als Ergebnis eines Selects ausgeben.
Dann hast Du die Tipparbeit nur einmal, und hast Die Chance deine Datensätze nöch einmal zu überprüfen.
(und Du findest auch die Doublette)

Gruß
K-H

omata 31. Mär 2009 21:36

Re: SQL: JOIN und UPDATE
 
wurde schon erwähnt, sorry.

ts-d 1. Apr 2009 09:11

Re: SQL: JOIN und UPDATE
 
Habe gerade die Lösung laufen, das per Code in Delphi zu programmieren, jeweils einen Wert auszulesen per FieldValues (aus Tabelle Rabatte.db) und den Wert dann per ExcelSQL (aus einer Abfrageinstanz heraus) in der Tabelle Auftragpos.db zu aktualisieren.

Mann-o-Mann dauert das lange, läuft schon ne halbe Stunde und ist erst halb durch! (ca. 11.000 Datensätze)

Bernhard Geyer 1. Apr 2009 09:16

Re: SQL: JOIN und UPDATE
 
Das ist halt BDE/Paradox. Wie schon oben vorgeschlagen kommst du mit TTable-Komponente und den dort verfügbaren Find/SetRange-Methoden schneller zum ziel. Frag mich aber nicht nach Code. BDE ist schon lange bei uns entsorgt.

ts-d 1. Apr 2009 11:26

Re: SQL: JOIN und UPDATE
 
... Code ist kein Problem.

Welches System würdest du den als Alternative wählen?
Möglichst eins, bei dem man nicht den ganzen alten Code komplett neu programmieren muss...

hoika 1. Apr 2009 11:47

Re: SQL: JOIN und UPDATE
 
Hallo,

und wieder die alte Frage nach der Datenbank ...

Firebird z.B. (www.ibphoenix.com, dort gibt es Artikel zum Umstieg)

Ich habe vor ein paar Jahren unsere Pdx-DB umgestellt.
Um das stellenweise neucodieren kommst du trotzdem nicht rum.

Ich war immer noch bei der BDE(SQL-Links).

Gerade bei grossen Tabellen ist TTable stellenweise grottenlahm,
ist ja auch nicht dazu gedacht.
Ich musste also eine TQuery nehmen und den schönen TTable-Code neuschreiben.

Dein aktuelles Problem kommt übrigens durch die Verwendung einer TQuery
beim Update.

Wenn alle benötigten Werte aus der Quelltabelle per TTable (SetRange)
holen würdest, also nicht einzeln,
und dann über eine TTable schreibst, geht es sehr viel schneller.

Pdx: TTable guttt
SQL-DB: TQuery guttt


Heiko

joachimd 2. Apr 2009 08:56

Re: SQL: JOIN und UPDATE
 
Zitat:

Zitat von hoika
Gerade bei grossen Tabellen ist TTable stellenweise grottenlahm,
ist ja auch nicht dazu gedacht.
Ich musste also eine TQuery nehmen und den schönen TTable-Code neuschreiben.

um solcherlei Probleme kommst Du herum, wenn Du ein DBMS wählst, das ISAM unterstützt. Advantage Database Server ist eines derer;)

hoika 2. Apr 2009 09:00

Re: SQL: JOIN und UPDATE
 
Hallo,

war das gerade versteckte Werbung ? ;)


Heiko

joachimd 2. Apr 2009 10:24

Re: SQL: JOIN und UPDATE
 
Zitat:

Zitat von hoika
war das gerade versteckte Werbung ? ;)

nein - eine offene;)

ts-d 2. Apr 2009 17:52

Re: SQL: JOIN und UPDATE
 
Hallo Heiko,

wie meinst du das: direkt über eine TTable gehen und nicht über die TQuery?
(entschuldige die vielleicht dumme Frage)

mkinzler 2. Apr 2009 17:59

Re: SQL: JOIN und UPDATE
 
Nein, weil bei einem modernen DBMS ein TTable ein Query mit der Abfrage
SQL-Code:
select * from <Tabelle>;
ist.

hoika 2. Apr 2009 19:26

Re: SQL: JOIN und UPDATE
 
Hallo ts-d,

ich meinte, dass du mindestens zum Schreiben eine TTable,
und keine TQuery benutzen sollst.


Heiko

mkinzler 2. Apr 2009 19:28

Re: SQL: JOIN und UPDATE
 
@Heiko: Warum? Sehe da keine Notwendigkeit

hoika 2. Apr 2009 19:32

Re: SQL: JOIN und UPDATE
 
Hallo minzler,

siehe #13

Wir reden wie gesagt von Paradox.

TQuery: lahm
TTable: schnell

Naja, meistens.


Heiko

mkinzler 2. Apr 2009 19:37

Re: SQL: JOIN und UPDATE
 
Ich habe mich durch den Verlauf der Diskussion auf eine falsche Fährte begeben. Bei Patadox wird ja der Query auf Tables abgebildet. Bei "richtigen" DBMS umgekehrt.

ts-d 3. Apr 2009 07:12

Re: SQL: JOIN und UPDATE
 
Liste der Anhänge anzeigen (Anzahl: 1)
Ich will's noch nicht ganz wahr haben. Die Krücke Access schafft's, und Delphi / Paradox nicht???

Testweise habe ich Delphi mal eine Aktualisierungsabfrage mit JOIN angelegt. Sie funktioniert:

UPDATE _auftragpos INNER JOIN _Rabatte ON [_auftragpos].Auftrnum = [_Rabatte].Auftrnum and [_auftragpos].Pos_h = [_Rabatte].Pos_h SET [_auftragpos].RABATTSATZ = [_Rabatte].[Rabattsatz] WHERE [_auftragpos].[pos_u] = 0;

wobei Tabelle 1 = auftragpos.db (Paradoxtabelle in Access importiert) und
Tabelle 2 = rabatte.db (ebenso)

und in Tabelle 2 Auftrnum + pos_h eindeutige Datensätze darstellen,
während in Tabelle 1 das nicht der Fall ist, weil die Unterpositionen noch mit dabei sind (daher die WHERE-Klausel "WHERE pos_u = o").

Ich schicke mal die Dateien mit (kleiner Auszug von ein paar Datensätzen):

1. Datenbank Access mit beiden Tabellen und der funktionierenden Abfrage
2. beide Tabellen im Paradoxformat

mkinzler 3. Apr 2009 07:17

Re: SQL: JOIN und UPDATE
 
Paradox ist halt total veraltet! Die BDE ist auch schon seit D6(!) als verlatet bezeichnet und wird seither nicht mehr weiterentwickelt. Nimm was gescheites und es geht. ( Access würde ich auch nicht verwenden)

Bernhard Geyer 3. Apr 2009 07:56

Re: SQL: JOIN und UPDATE
 
Zitat:

Zitat von ts-d
Ich will's noch nicht ganz wahr haben. Die Krücke Access schafft's, und Delphi / Paradox nicht???

Wenn Access eine Krücke (benötigt) dann benötigt man für Paradox einen Rollstuhl. Auch wenn Access keine optimale Engine darstellt, ist es doch um Welten bessser als Paradox. Paradox hat sein (merkbaren) Wurzeln in den 80ern und ist damit eher schon ein Dinosaurier der noch eingesetzten SW.

ts-d 3. Apr 2009 12:40

Re: SQL: JOIN und UPDATE
 
Ich habe jetzt selber eine Lösung gefunden, wenn auch keine sonderlich geniale - aber sie funktioniert und braucht nur ca. 10 Sekunden gegenüber der vorgeschlagenen, die hochgerechnet 4,5 Stunden braucht (500 Datensätze pro Minute bei ca. 118.000 Datensätzen !!!):

Durch SELECT eine Abfrage erzeugen, die die Werte beider Tabellen zusammenfasst:

SQL-Code:
SELECT

a.Auftrnum,
a.positnum,
a.menge,
a.modellnum,
a.ARTIKELBESCHR,
a.LPREISMSTOFF,
a.DIFFSOLLPREIS,
a.ZUBEHOER,
a.BESTAETPREIS,
a.EPREISRAB,
a.fz1,
a.mzbh,
a.bestpreis,
a.fz,
a.rabatt,
a.BETRAG,
a.RABATTBETRAG,
a.pos_h,
a.pos_u,
b.rabattsatz

FROM "auftragpos.db" a
   INNER JOIN "Rabatte.db" b
   ON a.Auftrnum = b.Auftrnum
   and a.Pos_h = b.Pos_h

WHERE a.pos_u = 0
Dieser Selectbefehl ist zu lang für SQL.Text := ... usw.
Daher mache ich's mit dem Befehl
Abfrage.SQL.LoadFromFile(Verzeichnis + Dateiname);

Dann erzeuge ich eine neue Instanz Batchmove, wähle die eben erzeugte Abfrage als Source und lasse den Batchmove über die Option batCopy (Mode) eine neue Tabelle erzeugen, die dann genau so aussieht, wie ich sie haben möchte.

[edit=mkinzler]SQL-Tag eingefügt Mfg, mkinzler[/edit]
Danke schön - ich lern's auch noch, vg Thomas


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:26 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