2016-06-30 11 views
1

Tabelle Attendance:UPDATE oder INSERT INTO funktioniert nicht in der Prozedur?

EMPL_KODE |EMPL_NAME |DATE_IN |TIME_IN |TIME_OUT|TOTAL_MIN |TOTAL_HOUR 
-------------------------------------------------------------------------- 
    001 | Michel |25.04.2016 |06:50 |15:40 |NULL  |NULL 
    002 | Clara  |25.04.2016 |06:15 |15:43 |NULL  |NULL 
    003 | Rafael |25.04.2016 |06:25 |15:45 |NULL  |NULL 
    001 | Michel |26.04.2016 |06:23 |15:42 |NULL  |NULL 
    002 | Clara  |26.04.2016 |06:10 |15:41 |NULL  |NULL 
    003 | Rafael |26.04.2016 |06:30 |15:42 |NULL  |NULL 
    001 | Michel |27.04.2016 |06:33 |15:42 |NULL  |NULL 
    002 | Clara  |27.04.2016 |06:54 |15:44 |NULL  |NULL 
    003 | Rafael |27.04.2016 |07:00 |15:45 |NULL  |NULL 

ich Erfolg Prozedur zu erstellen, haben Wert für Spalte TOTAL_MIN und TOTAL_HOUR mit dieser Syntax automatisch einzufügen:

SET TERM^; 
ALTER PROCEDURE UPDATEEMPLOYEES 
AS 
DECLARE VARIABLE EMPL_KODE CHAR(5); 
DECLARE VARIABLE EMPL_NAME VARCHAR (25); 
DECLARE VARIABLE TIME_IN TIMESTAMP; 
DECLARE VARIABLE TIME_OUT TIMESTAMP; 
DECLARE VARIABLE TOTAL_MINUTES INTEGER; 
DECLARE VARIABLE TOTAL_HOURS FLOAT; 

BEGIN 
FOR SELECT e.EMPL_KODE, e.EMPL_NAME, 
     CAST(a.DATE_IN + a.TIME_IN AS TIMESTAMP), 
     CAST(a.DATE_IN + a.TIME_OUT AS TIMESTAMP), 
     DATEDIFF(MINUTE,a.TIME_IN,a.TIME_OUT), 
     DATEDIFF(HOUR,a.TIME_IN,a.TIME_OUT) 
     FROM EMPLOYEE e 
     JOIN ATTENDANCE a 
     ON e.EMPL_KODE=a.EMPL_KODE 

INTO :EMPL_KODE,:EMPL_NAME,:TIME_IN,:TIME_OUT,TOTAL_MINUTES,TOTAL_HOURS 
DO 
     UPDATE ATTENDANCE a 
     set a.TOTAL_MINUTES=:TOTAL_MINUTES, 
     a.TOTAL_HOURS=:TOTAL_HOURS 
     WHERE a.EMPL_KODE=:EMPL_KODE; 

end^ 
SET TERM ;^

Aber das Problem ist, wie kann ich die Syntax schreiben direkt mit UPDATE oder INSERT INTO? Ich habe es versucht, aber immer noch nicht funktioniert.

Ich schreibe den gleichen Code wie die Firebird Anweisung.

UPDATE OR INSERT INTO 
    {tablename | viewname} [(<columns>)] 
    VALUES (<values>) 
    [MATCHING (<columns>)] 
    [RETURNING <values> [INTO <variables>]] 

<columns>  ::= colname [, colname ...] 
<values>  ::= value [, value ...] 
<variables> ::= :varname [, :varname ...] 

Hier ist mein Code:

Ich schreibe nicht die Returning, weil ich verstehe nicht, was es ist.

SET TERM^; 
ALTER PROCEDURE BLABLA(
    TOTAL_M INTEGER, 
    TOTAL_H FLOAT) 
AS 
BEGIN 
    UPDATE or INSERT INTO ATTENDANCE (TOTAL_MINUTES,TOTAL_HOURS) 
    VALUES (:TOTAL_M,:TOTAL_H) 
    MATCHING (EMPL_KODE); 
end^ 
SET TERM ;^

Nachdem ich die Aussage begehen, zeigt es die Fehlermeldung:

UPDATE OR INSERT Liste Feld entspricht nicht Klausel MATCHING

Was soll ich tun?

+0

Firebird a [MERGE INTO] hat auch (http://www.firebirdsql.org/refdocs/langrefupd25 -merge.html) DML-Anweisung für Upserts. – LukStorms

+0

Finden Sie die Antwort von ain für Ihr direktes Problem, aber ich glaube nicht, dass Ihr aktuelles 'update oder insert' genau genug ist, basierend auf der Tabelle, die Sie am Anfang Ihrer Frage zeigen; Ich würde erwarten, dass die Spaltenliste, die Werteliste und die Übereinstimmungsliste auch die Spalte "DATE_IN" enthalten. –

Antwort

0

Schließlich habe ich die Antwort von dieser http://www.firebirdfaq.org/faq336 bekam

SET TERM^; 
ALTER PROCEDURE UPDATEEMPLOYEEES 
AS 
begin 
UPDATE ATTANDENCE 
SET TOTAL_MINUTES=DATEDIFF(MINUTE,TIME_IN,TIME_OUT), 
    TOTAL_HOURS=DATEDIFF(MINUTE,TIME_IN,TIME_OUT)/60.0; 
END^ 
SET TERM ;^
3

Ich denke, das Problem ist, dass Sie MATCHING (EMPL_KODE) haben, aber Sie nicht die EMPL_KODE Spalte in Werteliste auflisten - wie erwarten Sie, dass die Engine herausfinden, welche Zeilen zu aktualisieren? Versuchen Sie so etwas wie:

SET TERM^; 
ALTER PROCEDURE BLABLA(
    E_KODE CHAR(5), 
    TOTAL_M INTEGER, 
    TOTAL_H FLOAT) 
AS 
BEGIN 
    UPDATE or INSERT INTO ATTENDANCE (TOTAL_MINUTES,TOTAL_HOURS, EMPL_KODE) 
    VALUES (:TOTAL_M,:TOTAL_H, :E_KODE) 
    MATCHING (EMPL_KODE); 
end^ 
SET TERM ;^
Verwandte Themen