![]() |
Datenbank: MySQL • Version: 5 • Zugriff über: UniDac
Daten in Tabelle korrigieren
Hallo Zusammen,
ich habe wieder ein MySQL-Problem, bei dem ich alleine nicht weiterkomme und bitte Euch um Hilfe. Ich habe eine Tabelle, in der ich Fertigungsauftragsdaten habe. Diese Tabelle kommt aus unserem ERP-System und sieht vereinfacht so aus: AuftragNr Arbeitsgang Rückmeldung 000004711 00000001 Fertig 000004711 00000002 Fertig 000004711 00000003 Fertig 000004711 00000004 Fertig 000004711 00000005 Dieser Arbeitsgang ist noch nicht fertig, deshalb steht dort kein "Fertig" drin. 000004711 00000006 000000815 00000001 Fertig 000000815 00000002 Fertig 000000815 00000003 Hier ist ein Rückmeldefehler, denn hier müsste auch "Fertig" stehen, aber hier steht nichts 000000815 00000004 Fertig 000000815 00000005 Fertig 000000815 00000006 000000815 00000007 000000815 00000008 Also alle Arbeitsgängen eines Auftrags, wo ein "Fertig" drinsteht, sind beendet. Wo nichts drinsteht, die sind noch nicht beendet. Es ist nicht möglich, dass Arbeitsgang 6 vor Arbeitsgang 5 gemacht wird. Deshalb ist in unserem Beispiel bei Auftrag 000000815 beim Arbeitsgang 3 ein Rückmeldefehler. Diese Fehler werden zwar irgendwann von der Produktionsplanung behoben, aber bis dahin verursachen sie Fehler in meinem Programm. Daher möchte ich gerne eine update-Anweisung anwenden, mit der ich solche Rückmeldefehler beheben kann. Leider habe ich keine Idee, wie ich das anstellen soll und hoffe, dass Ihr mir weiterhelft. Vielen Dank Patrick |
AW: Daten in Tabelle korrigieren
Vielleicht in dieser Art?
SQL-Code:
UPDATE
Tabelle A SET Rückmeldung = 'Fertig' WHERE Rückmeldung = '' AND EXISTS( SELECT * FROM Tabelle WHERE AuftragNr = A.AuftragNr AND Arbeitsgang > A.Arbeitsgang AND Rückmeldung = 'Fertig' ) |
AW: Daten in Tabelle korrigieren
Oder erstmal alle betroffenen finden:
Code:
und da dann ein Update drüber
Select AuftragNr||Arbeitsgang From Tabelle A
Where Rückmeldung is NUll And Arbeitsgang < ( Select Max(Arbeitsgang) From Tabelle Where AuftragNr=A.AuftragNr And Rückmeldung = 'Fertig' )
Code:
Nicht schön, aber selten...
UPDATE Tabelle A
SET Rückmeldung = 'Fertig' WHERE AuftragNr||Arbeitsgang in ("obigem Select") |
AW: Daten in Tabelle korrigieren
Hallo DeddyH,
vielen Dank für Deinen Vorschlag. Ich habe noch eine Frage: Du scheinst zwei verschiedene Tabellen zu verwenden, denn die eine Tabelle heißt Tabelle A und die andere nur Tabelle... Ich habe die Daten ja in einer Tabelle, daher habe ich es so versucht:
Delphi-Quellcode:
Leider funktioniert das nicht, weil ich in einer Update-Anweisung nicht die gleiche Tabelle in der SubQuery verwenden darf.
UPDATE
as400temp as A SET A.OATLKZ = '9' //Das ist das Feld für Rückmeldungen WHERE A.OATLKZ = '' AND EXISTS( SELECT * FROM as400temp as B WHERE B.WAAUNR = A.WAAUNR //Das ist das Feld für die AuftragsNr AND B.WAAUPO = A.WAAUPO //Das ist ein Zusatzfeld, dass zur AuftragsNr gehört AND B.OAAGNR > A.OAAGNR //Das ist das Feld für den Arbeitsgang AND B.OATLKZ = '9' Ich bekomme diese Fehlermeldung:
Delphi-Quellcode:
You can't specify target table 'A' for update in FROM clause
Kann mir da jemand weiterhelfen? Vielen Dank Patrick |
AW: Daten in Tabelle korrigieren
Hallo Jumpy,
Vielen Dank für Deinen Vorschlag. Wenn ich es nicht in einer SQL-Anweisung realisieren kann, werde ich ihn verwenden. Ich habe es gerade schon mal ausprobiert und das Ergebnis der Select-Anweisung scheint korrekt zu sein. Daraus könnte ich mir dann in Delphi eine Update-Anweisung zusammenbauen... Schöner wäre es aber mit einer Anweisung, aber es viel besser als wie ich es vor zwei Jahre gelöst habe (ich entwickel eine alte Software gerade neu), in der ich nämlich die relevanten Aufträge mittels einer For-Schleife aus allen Datensätzen heraus ermittelt habe....:oops: Gruß Patrick |
AW: Daten in Tabelle korrigieren
Ja, du kannst die betroffenen Datensätze in eine temp. Tabelle schreiben und dann in deinem UPDATE Statement benutzen.
Code:
CREATE TEMPORARY TABLE tmpTab
SELECT AuftragNr, Arbeitsgang FROM Tabelle A WHERE Rueckmeldung IS NULL AND Arbeitsgang < ( SELECT Max( Arbeitsgang ) FROM Tabelle WHERE AuftragNr = A.AuftragNr AND Rueckmeldung = 'Fertig' ); UPDATE Tabelle SET Rueckmeldung = 'Fertig' WHERE ( AuftragNr, Arbeitsgang ) IN ( SELECT AuftragNr, Arbeitsgang FROM tmpTab ); DROP TABLE tmpTab; ![]() Wenn du sicherstellen willst, dass diese Fehler nicht mehr auftauchen, so würde ich einen TRIGGER (INSERT,UPDATE) empfehlen, der dieses gewährleistet. |
AW: Daten in Tabelle korrigieren
Zitat:
Vielen Dank für die Vorschläge, dass sieht wirklich klasse aus!!! Ich glaube, dass ich es so schaffen kann. Zitat:
Aber mit TRIGGERN kenne ich mich gar nicht aus. Hast Du dafür einen guten Link? Vielen Dank für Eure Unterstützung bis hier Gruß Patrick |
AW: Daten in Tabelle korrigieren
Hier eine Lösung mit Triggern.
Da in einem Trigger die Tabelle selber nicht geändert werden kann, benötigt man eine weitere Tabelle, in der die überarbeiteten Werte eingetragen werden. Dadurch hat man aber auch eine Trennung zwischen der Eingangstabelle und der Tabelle mit der man letztendlich arbeitet. Unterschiede in den Tabellen können leicht erkannt werden und helfen auch bei der Fehlersuche/Optimierung. Hier die beiden Tabellen:
Code:
Das Feld AutoState habe ich nur eingeführt, damit man sehen kann, wo wirklich Änderungen durch diese Vorgaben vorgenommen wurden.
CREATE TABLE `as400temp` (
`AuftragNr` varchar(9) NOT NULL DEFAULT '', `Arbeitsgang` varchar(8) NOT NULL DEFAULT '', `Rueckmeldung` varchar(50) DEFAULT NULL, PRIMARY KEY (`AuftragNr`,`Arbeitsgang`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE TABLE `erpstat` ( `AuftragNr` varchar(9) NOT NULL DEFAULT '', `Arbeitsgang` varchar(8) NOT NULL DEFAULT '', `Rueckmeldung` varchar(50) DEFAULT NULL, `AutoState` tinyint(4) NOT NULL, PRIMARY KEY (`AuftragNr`,`Arbeitsgang`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; Der Inhalt des INSERT/UPDATE Triggers von as400temp sieht dabei wie folgt aus:
Code:
INSERT INTO erpstat ( AuftragNr, Arbeitsgang, Rueckmeldung, AutoState )
VALUES( NEW.AuftragNr, NEW.Arbeitsgang, NEW.Rueckmeldung, 0 ) ON DUPLICATE KEY UPDATE Rueckmeldung = NEW.Rueckmeldung, AutoState = 0; IF NOT ISNULL( NEW.Rueckmeldung ) THEN UPDATE erpstat SET Rueckmeldung = 'Fertig', AutoState = 1 WHERE AuftragNr = NEW.AuftragNr AND Arbeitsgang < NEW.Arbeitsgang AND Rueckmeldung IS NULL; ELSE IF ( SELECT COUNT(*) FROM erpstat WHERE AuftragNr = NEW.AuftragNr AND Arbeitsgang > NEW.Arbeitsgang AND Rueckmeldung IS NOT NULL ) THEN UPDATE erpstat SET Rueckmeldung = 'Fertig', AutoState = 1 WHERE AuftragNr = NEW.AuftragNr AND Arbeitsgang = NEW.Arbeitsgang; END IF; END IF; ![]() |
AW: Daten in Tabelle korrigieren
Hallo Sir Rufo,
ich bin gerade dabei, Deinen Ansatz mit der temporären Tabelle umzusetzen und komme leider an einem Fehlern nicht vorbei... So habe ich es versucht:
Delphi-Quellcode:
CREATE TEMPORARY TABLE tmpTab
SELECT WAAUNR, WAAUPO, OAAGNR FROM as400temp as A WHERE OATLKZ = '' AND OAAGNR < ( SELECT Max( OAAGNR ) FROM as400temp WHERE WAAUNR = A.WAAUNR AND WAAUPO = A.WAAUPO AND OATLKZ = '9' ) AND OAMANR not REGEXP 'HD|FA|KO'; //Das ist noch ein Zusatz, den ich vorher in meiner Software zusammenbauen muss //Bis hierhin scheint es zu funktionieren, denn wenn ich es alleine ausführe, dann kommt keine Fehlermeldung UPDATE as400temp SET OATLKZ = '9' WHERE ( WAAUNR, WAAUPO, OAAGNR ) IN ( SELECT WAAUNR, WAAUPO, OAAGNR FROM tmpTab ); //Ich nehme an, dass der Fehler an dieser Stelle ausgelöst wird. Die tmpTab wird nicht gefunden... DROP TABLE tmpTab; Die Fehlermeldung lautet: Unknown table 'tmptab' Hast Du oder jemand anderes eine Idee, was ich falsch mache? Vielen Dank Patrick |
AW: Daten in Tabelle korrigieren
Wenn du nur das SELECT Statement ausführst, werden dann Datensätze angezeigt?
Code:
und wenn du das hier ausführst:
SELECT WAAUNR, WAAUPO, OAAGNR
FROM as400temp as A WHERE OATLKZ = '' AND OAAGNR < ( SELECT Max( OAAGNR ) FROM as400temp WHERE WAAUNR = A.WAAUNR AND WAAUPO = A.WAAUPO AND OATLKZ = '9' ) AND OAMANR not REGEXP 'HD|FA|KO';
Code:
oder mal so
CREATE TEMPORARY TABLE tmpTab
SELECT WAAUNR, WAAUPO, OAAGNR FROM as400temp as A WHERE OATLKZ = '' AND OAAGNR < ( SELECT Max( OAAGNR ) FROM as400temp WHERE WAAUNR = A.WAAUNR AND WAAUPO = A.WAAUPO AND OATLKZ = '9' ) AND OAMANR not REGEXP 'HD|FA|KO'; SELECT * FROM tmpTab;
Code:
SELECT WAAUNR, WAAUPO, OAAGNR
FROM as400temp as A WHERE IFNULL( OATLKZ, '' ) = '' AND OAAGNR < ( SELECT Max( OAAGNR ) FROM as400temp WHERE WAAUNR = A.WAAUNR AND WAAUPO = A.WAAUPO AND OATLKZ = '9' ) AND OAMANR not REGEXP 'HD|FA|KO'; |
AW: Daten in Tabelle korrigieren
Hallo,
vielen Dank für die schnelle Antwort!!! Hier werden Daten angezeigt!
Delphi-Quellcode:
Hier kommt die Fehlermeldung: Table 'nedcom.tmptab' doesn't exist
SELECT WAAUNR, WAAUPO, OAAGNR
FROM as400temp as A WHERE OATLKZ = '' AND OAAGNR < ( SELECT Max( OAAGNR ) FROM as400temp WHERE WAAUNR = A.WAAUNR AND WAAUPO = A.WAAUPO AND OATLKZ = '9' ) AND OAMANR not REGEXP 'HD|FA|KO';
Delphi-Quellcode:
Hier werden die gleichen Daten wie oben angezeigt
CREATE TEMPORARY TABLE tmpTab
SELECT WAAUNR, WAAUPO, OAAGNR FROM as400temp as A WHERE OATLKZ = '' AND OAAGNR < ( SELECT Max( OAAGNR ) FROM as400temp WHERE WAAUNR = A.WAAUNR AND WAAUPO = A.WAAUPO AND OATLKZ = '9' ) AND OAMANR not REGEXP 'HD|FA|KO'; SELECT * FROM tmpTab;
Delphi-Quellcode:
Gruß
SELECT WAAUNR, WAAUPO, OAAGNR
FROM as400temp as A WHERE IFNULL( OATLKZ, '' ) = '' AND OAAGNR < ( SELECT Max( OAAGNR ) FROM as400temp WHERE WAAUNR = A.WAAUNR AND WAAUPO = A.WAAUPO AND OATLKZ = '9' ) AND OAMANR not REGEXP 'HD|FA|KO'; Patrick |
AW: Daten in Tabelle korrigieren
Führst du etwa jedes Statement einzeln aus?
|
AW: Daten in Tabelle korrigieren
Ich habe die ANweisungen erst zusammen ausgeführt, dann aber auch einzeln versucht...
Kann es sein, dass ich die Drop-Anweisung einzeln ausführen muss? Ohne die habe ich es jetzt irgendwie ans Laufen bekommen, habe aber keine Ahnung warum. Ich verwende den QueryBrowser. Kann es auch damit zusammenhängen? Ich bin etwas verwirrt... |
AW: Daten in Tabelle korrigieren
Also, wenn ich die Anweisungen jetzt einzeln durchgehe, scheinen sie zu laufen, aber zusammen geht im Query-Browser nicht. ABer vielleicht hat mein Programm damit keine Probleme. Ich bin zurzeit noch nicht an dem Punkt, dass ich mein Programm testen kann. Ich programmiere also gerade blind. Ich muss noch zwei große Proceduren fertig bekommen, dann kann ich das Programm testen...
Ich werde gleich mal eben ein kleines eigenes Programm machen... Melde mich gleich wieder. Danke Patrick |
AW: Daten in Tabelle korrigieren
Hallo Zusammen,
mit dieser Procedure funktioniert es:
Delphi-Quellcode:
Anregungen und Verbesserungen werden gerne angenommen!
procedure TMain.ButtonAktualisierenClick(Sender: TObject);
var AGS: string; I: integer; Query: TUniQuery; begin Query:=Main.MySelectQuery; //Normalerweise wird die Query der Procedure der Klasse übergeben, das habe hier nur für den Test gemacht... //Rückmeldefehler beheben AGS:=''; Query.SQL.Clear; //AGs die nicht korrigiert werden sollen holen Query.SQL.Add('select Wert from einstellungen '); Query.SQL.Add('where einstellung= :Einstellung '); Query.ParamByName('Einstellung').AsString:='Rueckm.nicht.korrigieren'; Query.Open; if not Query.Eof then begin AGS:=Query.Fields.Fields[0].Value; Query.Next; if Query.RecordCount>1 then begin for I:=1 to Query.RecordCount -1 do begin AGS:=AGS+'|'+Query.Fields.Fields[0].Value; Query.Next; end; end; end; Query.SQL.Clear; Query.SQL.Add('CREATE TEMPORARY TABLE tmpTab '); Query.SQL.Add('SELECT WAAUNR, WAAUPO, OAAGNR '); Query.SQL.Add('FROM as400temp as A '); Query.SQL.Add('WHERE OATLKZ = '''''); Query.SQL.Add('AND OAAGNR < '); Query.SQL.Add('( SELECT Max( OAAGNR ) '); Query.SQL.Add('FROM as400temp '); Query.SQL.Add('WHERE WAAUNR = A.WAAUNR '); Query.SQL.Add('AND WAAUPO = A.WAAUPO '); Query.SQL.Add('AND OATLKZ = ''9'' ) '); Query.SQL.Add('AND OAMANR not REGEXP '''+AGS+'''; '); Query.SQL.Add('UPDATE as400temp '); Query.SQL.Add('SET OATLKZ = ''9''' ); Query.SQL.Add(' WHERE ( WAAUNR, WAAUPO, OAAGNR ) IN ( SELECT WAAUNR, WAAUPO, OAAGNR '); Query.SQL.Add('FROM tmpTab ); '); Query.SQL.Add('DROP TABLE tmpTab; '); Query.Execute; end; Vielen Dank für die Unterstützung!!! Gruß Patrick |
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:15 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz