| Autor |
Beitrag |
dierk
Hält's aus hier
Beiträge: 9
|
Verfasst: Fr 18.11.05 20:05
Hallo ich wollte eigentlich mal meine erste stored procedure mit Firebird 1.5 machen.
Aber jetzt mach ich schon den ganzen Mittag rum und komm nicht drauf wo das Problem liegen kann. Eigentlich wollte ich ne automatisierte Routine haben, die mir schon vorhandene Datensätze dann nur updatet. Aber irgendwie bin ich zu blöde dafür.
SQL-Anweisung 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24:
| CREATE PROCEDURE INSUPD_MESSWERT( iStation SMALLINT, iMesspunkt SMALLINT, iZeitpunkt TIMESTAMP, iStatus SMALLINT, iMesswert DOUBLE PRECISION ) AS BEGIN INSERT INTO Messwerte(Station, Messpunkt, Zeitpunkt, Status, Messwert) VALUES (:iStation, :iMesspunkt, :iZeitpunkt, :iStatus, :iMesswert);
WHEN SQLCODE -803 do
UPDATE Messwerte SET Station = :iStation, Messpunkt = :iMesspunkt, Zeitpunkt = :iZeitpunkt, Status = :iStatus, Messwert = :iMesswert WHERE (Station=:iStation) and (Messpunkt=:iMesspunkt) and (Zeitpunkt=:iZeitpunkt) END
END |
Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| //////////////////////////////////////////////////////////// Statement #1: Dynamic SQL Error SQL error code = -104 Unexpected end of command
Statement #2: Dynamic SQL Error SQL error code = -104 Token unknown - line 4, char 3 WHEN
//////////////////////////////////////////////////////////// |
Moderiert von raziel: Code- durch Sql-Tags ersetzt.
|
|
hansa
      
Beiträge: 3079
Erhaltene Danke: 9
|
Verfasst: Fr 18.11.05 20:33
Ist du unübersichtlich.  Guck mal meine altbewährte Konstruktion an :
Pseudocode 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17:
| CREATE PROCEDURE TABELLESP (..Paramter..) AS DECLARE VARIABLE AENDERN INTEGER; begin AENDERN = -1; select ID from TABELLE where (???) into :AENDERN; if (AENDERN < 0) then begin insert into TABELLE (..Felder..) values (:Feld1,:Feld2...); end else begin update TABELLE set FELD1 = :Feld1 where (???); end suspend; end^ |
Bei Deiner Variante wird versucht, ein Insert zu erzwingen auch wenn es gar nicht geht. Und dann ist es eben am Ende zu spät. 
_________________ Gruß
Hansa
|
|
alex517
      
Beiträge: 60
D7Ent, FB, FIBPlus
|
Verfasst: Fr 18.11.05 23:55
Hi dierk,
oder so:
SQL-Anweisung 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19:
| CREATE PROCEDURE INSUPD_MESSWERT( iStation SMALLINT, iMesspunkt SMALLINT, iZeitpunkt TIMESTAMP, iStatus SMALLINT, iMesswert DOUBLE PRECISION ) AS BEGIN IF (EXISTS(SELECT * FROM Messwerte WHERE (Station=:iStation) and (Messpunkt=:iMesspunkt) and (Zeitpunkt=:iZeitpunkt)) THEN UPDATE Messwerte SET Station = :iStation, Messpunkt = :iMesspunkt, Zeitpunkt = :iZeitpunkt, Status = :iStatus, Messwert = :iMesswert WHERE (Station=:iStation) and (Messpunkt=:iMesspunkt) and (Zeitpunkt=:iZeitpunkt) ELSE INSERT INTO Messwerte(Station, Messpunkt, Zeitpunkt, Status, Messwert) VALUES (:iStation, :iMesspunkt, :iZeitpunkt, :iStatus, :iMesswert); END |
|
|
dierk 
Hält's aus hier
Beiträge: 9
|
Verfasst: Sa 19.11.05 17:31
SQL-Anweisung 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27:
| CREATE PROCEDURE INSUPD_MESSWERT( iStation SMALLINT, iMesspunkt SMALLINT, iZeitpunkt TIMESTAMP, iStatus SMALLINT, iMesswert DOUBLE PRECISION ) AS DECLARE VARIABLE AENDERN INTEGER; begin AENDERN = -1; select Station from Messwerte WHERE (Station=:iStation) and (Messpunkt=:iMesspunkt) and (Zeitpunkt=:iZeitpunkt) into :AENDERN; if (AENDERN < 0) then begin INSERT INTO Messwerte(Station, Messpunkt, Zeitpunkt, Status, Messwert) VALUES (:iStation, :iMesspunkt, :iZeitpunkt, :iStatus, :iMesswert); end else begin UPDATE Messwerte SET Station = :iStation, Messpunkt = :iMesspunkt, Zeitpunkt = :iZeitpunkt, Status = :iStatus, Messwert = :iMesswert WHERE (Station=:iStation) and (Messpunkt=:iMesspunkt) and (Zeitpunkt=:iZeitpunkt); end suspend; end^ |
Danke so tut´s
Moderiert von raziel: Code- durch SQL-Tags ersetzt
|
|
delphiDeveloper
      
Beiträge: 48
|
Verfasst: Sa 19.11.05 18:10
Titel: eleganter noch mit neuem Feature ROW_COUNT in Firebird 1.5
Ab Firbird 1.5 kommst du ohne deine Variable aus und auch das select vorher brauchst du nicht mehr.
Du machst einfach ein update un wertest ROW_COUNT aus.
Ist ROW_COUNT = 0 dann machst du halt deinen insert.
ROW_COUNT hat immer den Wert der letzten INSERT/UPDATE/DELETE Operation
Bei Selects liefert es immer 0.
gruss
DD
SQL-Anweisung 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27:
| CREATE PROCEDURE INSUPD_MESSWERT( iStation SMALLINT, iMesspunkt SMALLINT, iZeitpunkt TIMESTAMP, iStatus SMALLINT, iMesswert DOUBLE PRECISION ) AS
begin
UPDATE Messwerte SET Station = :iStation, Messpunkt = :iMesspunkt, Zeitpunkt = :iZeitpunkt, Status = :iStatus, Messwert = :iMesswert WHERE (Station=:iStation) and (Messpunkt=:iMesspunkt) and (Zeitpunkt=:iZeitpunkt);
if (ROW_COUNT = 0) then begin INSERT INTO Messwerte(Station, Messpunkt, Zeitpunkt, Status, Messwert) VALUES (:iStation, :iMesspunkt, :iZeitpunkt, :iStatus, :iMesswert); end
suspend; end^ |
|
|
dierk 
Hält's aus hier
Beiträge: 9
|
Verfasst: Sa 19.11.05 21:58
Klasse! Da müssten dann die tausende von Datensätze, die ich möglichst schnell aus einer Access-Datenbank einlesen muss, auch schneller upgedatet/eingefügt sein.
Danke!
P.S. Können SPs auch auf dem embedded Server ausgeführt werden?
|
|
hansa
      
Beiträge: 3079
Erhaltene Danke: 9
|
Verfasst: So 20.11.05 01:32
Keine Bange, das ist egal ob embedded oder nicht. Zumindest für das Programm und die DB. Die Einschränkung auf Einzelplatz ist das einzige was zu beachten ist. Hatte letztens Bedenken bei 2 angesprochenen DB's, aber auch das ging problemlos. Würde mich nicht mal wundern, wenn Multitasking auf einem Rechner sogar gehen würde (aber nicht getestet !).
_________________ Gruß
Hansa
|
|
|