2012-07-02 111 views
1

我的觸發器接受輸入。 (NEW:input_id)使用此輸入,它將使用動態生成的查詢生成新的ID。動態生成的查詢的指令 存儲在QUERY_REF中。
它使用遊標檢索query_ids用於產生動態查詢:PL/SQL:插入或更新觸發器「select count」結果

CURSOR C_QUERY IS 
    SELECT QUERY_ID 
    FROM QUERY_REF 
    WHERE GENERATE_IND='Y'; 

OPEN C_QUERY; 

LOOP 
    FETCH C_QUERY INTO QUERY_ID_RET; 
    EXIT WHEN C_QUERY%NOTFOUND; 

INPUT_ID和QUERY_ID_RET已經成功地使用在功能gethostID創建Output_ID。

我想運行插入,基於是否找到記錄進行更新。選擇計數返回0. 我發現爲什麼選擇計數返回0 - 我引用了錯誤的表。我仍然不知道爲什麼這是檢索舊數據。這裏是整個觸發:

create or replace 
TRIGGER INPUT_AUTO_QUERY_TRIG 
AFTER INSERT OR UPDATE 
ON INPUT_TABLE 
FOR EACH ROW 
DECLARE 
    ACTION_VALUE  VARCHAR2(6); 
    HOLD_EVENT_ID  VARCHAR2(256); 
    HOLD_USER_ID  VARCHAR2(30); 
    HOLD_PK_VALUE  INTEGER(10); 
    HOLD_AUDIT_ITEM_ID INTEGER(10); 
    QUERY_ID_RET  NUMBER; 
    resultcount  NUMBER; 
    HostID  VARCHAR2(256); 
    QUERY_ID  NUMBER; 
    INPUT_ID   NUMBER(38,0); 
    GENERATE_IND  VARCHAR2(1); 
    pragma autonomous_transaction; 
CURSOR C_QUERY IS 
    SELECT QUERY_ID 
    FROM QUERY_REF 
    WHERE GENERATE_IND='Y'; 
BEGIN 

OPEN C_QUERY; 

LOOP 
    FETCH C_QUERY INTO QUERY_ID_RET; 
    EXIT WHEN C_QUERY%NOTFOUND; 

SELECT AUDIT_ID, USER_ID 
    INTO HOLD_EVENT_ID, HOLD_USER_ID 
    FROM AUDIT_EVENT_TEMP 
    WHERE SESSION_ID = SYS_CONTEXT('USERENV', 'SESSIONID'); 

    OutputID:=getHostID(:NEW.INPUT_ID,QUERY_ID_RET); 

    IF INSERTING THEN 
    INSERT INTO DETAIL 
    (
    DETAIL_ID, 
    INPUT_ID, 
    OUTPUT_ID, 
    QUERY_ID, 
    ACTIVE_IND, 
    CREATED_BY, 
    DATE_CREATED, 
    MODIFIED_BY, 
    DATE_MODIFIED 
) VALUES 
    (
    DETAIL_SEQ.NEXTVAL, 
    :NEW.INPUT_ID, 
    OutputID, 
    QUERY_ID_RET, 
    'Y', 
    HOLD_USER_ID, 
    SYSDATE, 
    HOLD_USER_ID, 
    SYSDATE 
); 

ELSIF UPDATING THEN 

SELECT COUNT(QUERY_ID) INTO resultcount FROM DETAIL WHERE    INPUT_ID=:NEW.INPUT_ID AND QUERY_ID=QUERY_ID_RET; 
    IF resultcount>0 THEN 
    UPDATE PATIENT_DATA_SOURCE 
    SET 
    HOST_ID = HostID, 
    ACTIVE_IND ='Y', 
    MODIFIED_BY =HOLD_USER_ID, 
    DATE_MODIFIED =SYSDATE 
    WHERE INPUT_ID=:NEW.INPUT_ID 
    AND QUERY_ID=QUERY_ID_RET; 

--don't want to change: DETAIL_ID,QUERY_ID,INPUT_ID,CREATED_BY,   DATE_CREATED in update 

    ELSE 
     INSERT INTO DETAIL 
    (
    DETAIL_ID, 
    INPUT_ID, 
    HOST_ID, 
    QUERY_ID, 
    ACTIVE_IND, 
    CREATED_BY, 
    DATE_CREATED, 
    MODIFIED_BY, 
    DATE_MODIFIED 
) VALUES 
    (
    DETAIL_SEQ.NEXTVAL, 
    :NEW.INPUT_ID, 
    HostID, 
    QUERY_ID_RET, 
    'Y', 
    HOLD_USER_ID, 
    SYSDATE, 
    HOLD_USER_ID, 
    SYSDATE 
); 
END IF; 
--end if insert or update inside update 

END IF; 
--end IF UPDATING 
END LOOP; 
Close C_QUERY; 

COMMIT; 
END INPUT_AUTO_QUERY_TRIG; 
--end trigger 
+0

你有兩個'IF INSERTING ...'行在開頭。我不知道這是否是故意的,但是就像張貼的那樣,似乎'ELSIF UPDATING ...'永遠不會被觸及,因爲它在'IF INSERTING ...'外部。 –

+0

謝謝,這是一個複製錯誤。 –

+0

你可以發佈完整的觸發器嗎? – Ben

回答

1

有使用SELECT COUNT(*)的觸發 沒有限制 - 除非是在桌子上 觸發器是在(一個突變 表的可能性)來定義。

http://psoug.org/reference/table_trigger.html

是否 SELECT COUNT(*)FROM query_str_ref WHERE INPUT_ID =:NEW.INPUT_ID AND QUERY_ID = QUERY_ID_RET;

在SQLPLUS會話中自行工作並返回一個 計數超過零?

如果該行返回正確的計數外 觸發,那麼無論是在觸發東西可以 被撞擊的次數達到或 行可能不會在所有達到前行。

如果該行不返回正確的計數 觸發之外,那麼它可能是一個好主意 檢查QUERY_STR_REF表數據, 新值輸入ID和

另外,你確定光標/ FETCH
上QUERY_REF設置QUERY_ID_RET要麼是內部 從所述觸發或訪問, 並沒有干擾(QUERY_REF是 不被觸發語句修改的)?

+0

非常感謝。我很擔心select trigger在觸發器內不起作用。 –

+0

只是一個筆記; SELECT COUNT(*)佔用的時間可能會非常容易地增長,具體取決於表中的索引等。這可能會減慢您觸發的表上的插入。 –

+0

我發現我無法在函數內執行動態查詢 - 它使用舊數據。我正在使用該函數來創建動態查詢,並在觸發器中運行查詢。我收到此錯誤:ORA-00923:FROM關鍵字找不到預期的地方。 –