Autor Beitrag
dierk
Hält's aus hier
Beiträge: 9



BeitragVerfasst: 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. :autsch:

ausblenden 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);

  /*Doppelter Primärindex */
  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



ausblenden 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 user profile iconraziel: Code- durch Sql-Tags ersetzt.
hansa
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 3079
Erhaltene Danke: 9



BeitragVerfasst: Fr 18.11.05 20:33 
Ist du unübersichtlich. 8) Guck mal meine altbewährte Konstruktion an :

ausblenden 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. :mrgreen:

_________________
Gruß
Hansa
alex517
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 60


D7Ent, FB, FIBPlus
BeitragVerfasst: Fr 18.11.05 23:55 
Hi dierk,

oder so:
ausblenden 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 Threadstarter
Hält's aus hier
Beiträge: 9



BeitragVerfasst: Sa 19.11.05 17:31 
ausblenden 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 user profile iconraziel: Code- durch SQL-Tags ersetzt
delphiDeveloper
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 48



BeitragVerfasst: 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

ausblenden 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 Threadstarter
Hält's aus hier
Beiträge: 9



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 3079
Erhaltene Danke: 9



BeitragVerfasst: 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