触发器问题:ORA-00905:缺少关键字

时间:2016-09-23 15:29:38

标签: oracle plsql triggers

我尝试在插入特定表格后满足特定条件时将记录插入另一个表格( tableb )( tablea ) 所以我创建了一个触发器来检查上面的内容, condition:插入tablea后,检查tablea中的price的总和是否大于某个值,如果是,则将tino插入tableb。

下面的脚本将重新创建我目前面临的问题。需要另外付出代价。

-- create the tables
CREATE TABLE tablea
(
   tino NUMBER not null,
   price VARCHAR2(200),
   dated date
)
partition by range (DATED)
(
 partition PART_201608 values less than (TO_DATE(' 2016-09-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')),
partition PART_201609 values less than (TO_DATE(' 2016-10-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')),
partition PART_201610 values less than (TO_DATE(' 2016-11-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN'))
)

--INSERT VALUES
 INSERT INTO tablea (tino,price,dated)VALUES('1234567',10,SYSDATE);
  COMMIT;
  INSERT INTO tablea (tino,price,dated)VALUES('1234560',20,SYSDATE);
  COMMIT;
   -- create table table which once condition is met,, data is written into
 CREATE TABLE tableb(tino number);


-- CREATE THE TRIGGER
CREATE OR REPLACE TRIGGER trg1
AFTER INSERT
ON tablea
FOR EACH ROW

DECLARE
v_price NUMBER;
v_partition VARCHAR2(20) := 'PART_'||TO_CHAR(SYSDATE,'YYYYMM');
v_tino VARCHAR2(20) := :NEW.tino;
sql_smt VARCHAR2(1000) := '';

BEGIN
  sql_smt :='
      SELECT SUM(price) price INTO v_price
      FROM tablea PARTITION('||v_partition||')
       WHERE tino = '||''''||v_tino||''''||'';

 BEGIN
   EXECUTE IMMEDIATE sql_smt;
   EXCEPTION
   WHEN OTHERS THEN
   DBMS_OUTPUT.PUT_LINE(SQLERRM);
   DBMS_OUTPUT.PUT_LINE('QUERY='|| sql_smt);
 END;

--DBMS_OUTPUT.PUT_LINE('PRICE  =' || v_price);

 IF v_price >= 15 THEN
   INSERT INTO tableb (tino) VALUES (v_tino);
   COMMIT;
  END IF; 
 END;
  -- test the trigger 
   INSERT INTO tablea(tino,price,dated) VALUES('1234567',10,sysdate);
  COMMIT;

应该返回ORA-00905:缺少关键字

 DBMS_OUTPUT.PUT_LINE(SQLERRM);

返回:

SELECT SUM(price) price INTO v_price
FROM tablea PARTITION(PART_201609)
WHERE tino = '1234567'

哪个应该没有问题

任何指针??

1 个答案:

答案 0 :(得分:1)

INTO v_price应该是execute immediate语句的一部分,而不是动态SQL的一部分。

btw我想

WHERE tino = '||''''||v_tino||''''||'';

可以简化为

WHERE tino = '''||v_tino||'''';

甚至更好,

WHERE tino = :tino';

v_tino作为绑定变量传递,类似于

execute immediate xyz into v_price using v_tino;