![]() |
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'; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:44 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