PL / SQL:插入或更新触发器“选择计数”结果

时间:2012-07-02 15:51:44

标签: oracle plsql triggers

我的触发器需要输入。 (NEW:input_id)使用此输入,它将使用动态生成的查询生成新ID。说明 动态生成的查询存储在QUERY_REF中 它使用游标检索query_ids以生成动态查询:

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 - 我引用了错误的表。我仍然不知道为什么这是检索旧的dat。这是整个触发器:

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

1 个答案:

答案 0 :(得分: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和

另外,你确定CURSOR / FETCH
在QUERY_REF上设置QUERY_ID_RET在里面 触发器或可从触发器访问, 并且没有干扰(QUERY_REF是 没有被触发声明改变?)