1

私は次のステートメントを使用しています:

query_str='SELECT :NEW.FIRST_NAME||:NEW.LAST_NAME INTO  HostID 
FROM INPUT_TABLE WHERE INPUT_ID='

トリガーのコードは次のとおりです。

EXECUTE IMMEDIATE query_str ||:NEW.INPUT_ID;

INPUT_TABLEの更新時に次のエラーが発生します:ORA-01008:すべての変数がバインドされていません

input_id = 111のレコードを更新する場合、Oracleは次のステートメントを実行するだけだと思います。

SELECT :NEW.FIRST_NAME||:NEW.LAST_NAME INTO  HostID 
FROM INPUT_TABLE WHERE INPUT_ID=111

なぜバインディングの問題があるのですか?

SQLDeveloperを使用しています。

create or replace   
TRIGGER DATA_DETAIL_TRIG
AFTER INSERT OR UPDATE
ON INPUT_TABLE
FOR EACH ROW
 DECLARE
   DATA_SOURCE_ID_RET  NUMBER;
   resultcount        NUMBER;
   query_str          VARCHAR2(512);
   using_cl          VARCHAR2(512);
   HostId      VARCHAR2(256);
   DATA_SOURCE_ID       NUMBER;
   INPUT_ID         NUMBER(38,0);
   AUTOGENERATE_IND       VARCHAR2(1);
   autogen_const varchar(200);
   pragma autonomous_transaction;
   CURSOR C_DATA_SOURCES IS 
    SELECT DATA_SOURCE_ID
    FROM DATA_SOURCE_DETAIL
    WHERE AUTOGENERATE_IND='Y'
    AND DATA_SOURCE_REF.ACTIVE_IND='Y';
BEGIN


OPEN C_DATA_SOURCES;
LOOP
  FETCH C_DATA_SOURCES INTO DATA_SOURCE_ID_RET;
  EXIT WHEN C_DATA_SOURCES%NOTFOUND;
    query_str:=getHostQuery( DATA_SOURCE_ID_RET);
--SELECT :FIRST_NAME||:LAST_NAME||to_char(:DOB,'yyyy/mm/dd')    
From INPUT_TABLE WHERE     INPUT_ID=:INPUT_ID
using_cl:=getHostUsing(DATA_SOURCE_ID_RET);
--:NEW.FIRST_NAME, :NEW.LAST_NAME, :NEW.DOB, :NEW.INPUT_ID
EXECUTE IMMEDIATE query_str  INTO HostId USING using_cl;

  IF INSERTING THEN
    INSERT INTO DETAIL_TABLE
  (
  DETAIL_ID,
  INPUT_ID,
  HOST_ID,
  DATA_SOURCE_ID,
  NOTE,
  DATE_MODIFIED
  ) VALUES
  (
   DETAIL_SEQ.NEXTVAL,
    :NEW.INPUT_ID,
    HostId,
    DATA_SOURCE_ID_RET,
    'Autogenerate Data Source Insert for Insert Input',
    SYSDATE
  );

ELSIF UPDATING THEN



SELECT COUNT(DATA_SOURCE_ID) INTO resultcount FROM DETAIL_TABLE WHERE     
INPUT_ID=:NEW.INPUT_ID AND DATA_SOURCE_ID=DATA_SOURCE_ID_RET;
  IF resultcount>0 THEN


    UPDATE DETAIL_TABLE
    SET
  HOST_ID = HostId,
  NOTE ='Autogenerate Data Source Update for Update Input',
  DATE_MODIFIED =SYSDATE
  WHERE INPUT_ID=:NEW.INPUT_ID
  AND DATA_SOURCE_ID=DATA_SOURCE_ID_RET;


  ELSE
      INSERT INTO DETAIL_TABLE
  (
  DETAIL_ID,
  INPUT_ID,
  HOST_ID,
  DATA_SOURCE_ID,
  NOTE,
  DATE_MODIFIED
  ) VALUES
  (
  DETAIL_SEQ.NEXTVAL,
  :NEW.INPUT_ID,
  HostId,
   DATA_SOURCE_ID_RET,
   'Autogenerate Data Source Insert for Update Input ',

    SYSDATE
  );
END IF;
--end if insert or update inside update

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

COMMIT;
END DATA_DETAIL_TRIG;
--end trigger
4

2 に答える 2

3

:new変数を引用符で囲むと、Oracleはそれらの意味を特別なトリガー変数として失い、通常のバインド変数として解釈します。おそらくUSING、動的SQLで句を使用する必要があります。何かのようなもの

query_str:='SELECT :FIRST_NAME||:LAST_NAME
 FROM INPUT_TABLE WHERE INPUT_ID=:ID';
EXECUTE IMMEDIATE query_str INTO HostID USING 
  :NEW.FIRST_NAME,:NEW.LAST_NAME,:NEW.INPUT_ID;

アップデート。

詳細が明らかになると、なぜクエリを実行する必要があるのでしょうか。私が見ることができることから、あなたはただHostIDのいくつかの値から構成しますINPUT_TABLE。ただし、同じテーブルにトリガーが既にアタッチされているため、必要なすべての値がすでにあり、簡単に実行できます。

HostID := :NEW.FIRST_NAME||:NEW.LAST_NAME;

あなたのアプローチは、別のテーブルをクエリする場合にのみ意味があります。この場合、前述したように、引用し:NEWたり:OLD、に配置したりすることはできませんUSING。ただし、それらから他の値を作成することもできます。

于 2012-07-03T21:22:48.403 に答える
0

@Alex:以下がトリガーです。

create or replace   
TRIGGER DATA_DETAIL_TRIG
AFTER INSERT OR UPDATE
ON INPUT_TABLE
FOR EACH ROW
 DECLARE
   DATA_SOURCE_ID_RET  NUMBER;
   resultcount        NUMBER;
   query_str          VARCHAR2(512);
   using_cl          VARCHAR2(512);
   HostId      VARCHAR2(256);
   DATA_SOURCE_ID       NUMBER;
   INPUT_ID         NUMBER(38,0);
   AUTOGENERATE_IND       VARCHAR2(1);
   autogen_const varchar(200);
   pragma autonomous_transaction;
   CURSOR C_DATA_SOURCES IS 
    SELECT DATA_SOURCE_ID
    FROM DATA_SOURCE_DETAIL
    WHERE AUTOGENERATE_IND='Y'
    AND DATA_SOURCE_REF.ACTIVE_IND='Y';
BEGIN


OPEN C_DATA_SOURCES;
LOOP
  FETCH C_DATA_SOURCES INTO DATA_SOURCE_ID_RET;
  EXIT WHEN C_DATA_SOURCES%NOTFOUND;
    query_str:=getHostQuery( DATA_SOURCE_ID_RET);
--SELECT :FIRST_NAME||:LAST_NAME||to_char(:DOB,'yyyy/mm/dd')    
From INPUT_TABLE WHERE     INPUT_ID=:INPUT_ID
using_cl:=getHostUsing(DATA_SOURCE_ID_RET);
--:NEW.FIRST_NAME, :NEW.LAST_NAME, :NEW.DOB, :NEW.INPUT_ID
EXECUTE IMMEDIATE query_str  INTO HostId USING using_cl;

  IF INSERTING THEN
    INSERT INTO DETAIL_TABLE
  (
  DETAIL_ID,
  INPUT_ID,
  HOST_ID,
  DATA_SOURCE_ID,
  NOTE,
  DATE_MODIFIED
  ) VALUES
  (
   DETAIL_SEQ.NEXTVAL,
    :NEW.INPUT_ID,
    HostId,
    DATA_SOURCE_ID_RET,
    'Autogenerate Data Source Insert for Insert Input',
    SYSDATE
  );

ELSIF UPDATING THEN



SELECT COUNT(DATA_SOURCE_ID) INTO resultcount FROM DETAIL_TABLE WHERE     
INPUT_ID=:NEW.INPUT_ID AND DATA_SOURCE_ID=DATA_SOURCE_ID_RET;
  IF resultcount>0 THEN


    UPDATE DETAIL_TABLE
    SET
  HOST_ID = HostId,
  NOTE ='Autogenerate Data Source Update for Update Input',
  DATE_MODIFIED =SYSDATE
  WHERE INPUT_ID=:NEW.INPUT_ID
  AND DATA_SOURCE_ID=DATA_SOURCE_ID_RET;


  ELSE
      INSERT INTO DETAIL_TABLE
  (
  DETAIL_ID,
  INPUT_ID,
  HOST_ID,
  DATA_SOURCE_ID,
  NOTE,
  DATE_MODIFIED
  ) VALUES
  (
  DETAIL_SEQ.NEXTVAL,
  :NEW.INPUT_ID,
  HostId,
   DATA_SOURCE_ID_RET,
   'Autogenerate Data Source Insert for Update Input ',

    SYSDATE
  );
END IF;
--end if insert or update inside update

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

COMMIT;
END DATA_DETAIL_TRIG;
--end trigger
于 2012-07-06T21:58:25.390 に答える