Oracle 复合触发器:尝试获取日期最大值列时遇到 PLS-00103
Oracle Compound Trigger : PLS-00103 Encountered when Attempting to get Max of Date Column
我正在尝试构建一个触发器,当 table A 的相应 end_date 更新时,它将使用最大值 end_date 列更新 Table B。
这样我就可以计算并保存我之前保存的日期与我希望从 Table A.
不断更新的最大结束日期之间的日期差异
到目前为止,复合触发器似乎是一个有效的解决方案,因为我的行触发器没有完全涵盖所有用例,但是,我得到了标题中所述的错误。
完整错误:
PLS-00103: Encountered the symbol ")" when expecting one of the following: current delete exists prior
我试图找出我可能忽略的任何语法错误,但到目前为止我无法取得进展。
数据库版本似乎也正确,因为我使用的是 oracle 11g,应该支持复合触发器。
这就是前面提到的SQL:
CREATE OR REPLACE TRIGGER DATE_DIFF_CALC_A
FOR UPDATE OR INSERT OF END_ON ON TABLE_A
COMPOUND TRIGGER
TYPE temp_record IS RECORD (
COUNTER NUMBER,
B_ID TABLE_B.id%TYPE,
U_ID TABLE_B.U_ID%TYPE,
U_TYPE TABLE_B.U_TYPE%TYPE,
U_VOL_NO TABLE_B.U_VOL_NO%TYPE,
MAX_DATE TABLE_B.MAX_DATE%TYPE,
);
TYPE temp_table IS TABLE OF temp_record INDEX BY PLS_INTEGER;
row_record temp_table;
AFTER EACH ROW IS
COUNTER NUMBER;
MAX_DATE DATE;
B_ID NUMBER;
BEGIN
SELECT COUNT(*), MAX_DATE, ID
INTO COUNTER,
MAX_DATE,
B_ID
FROM TABLE_B
WHERE U_ID = :NEW.U_ID
AND U_TYPE = :NEW.TYPE AND U_VOL_NO = :NEW.U_VOL_NO GROUP BY ID, MAX_DATE;
-- Tool I am using for query tells me there is an error in this line, but there's nothing here :(
row_record(row_record.COUNT + 1).COUNTER := COUNTER;
row_record(row_record.COUNT).MAX_DATE := MAX_DATE;
row_record(row_record.COUNT).B_ID := B_ID;
row_record(row_record.COUNT).U_ID := :NEW.U_ID;
row_record(row_record.COUNT).U_TYPE := :NEW.TYPE;
row_record(row_record.COUNT).U_VOL_NO := :NEW.U_VOL_NO;
END AFTER EACH ROW;
AFTER STATEMENT IS
new_max_enddate TABLE_B.MAX_DATE%TYPE;
BEGIN
FOR indx IN 1 .. row_record.COUNT
LOOP
SELECT MAX(a.end_on)
INTO new_max_enddate
from TABLE_A a, TABLE_C C
where a.c_id = c.id and UPPER(c.place_name) not like 'XTEST%'
and a.status not in ('1', '2', '3', '4')
and a.U_ID = row_record(indx).U_ID
and a.TYPE = row_record(indx).U_TYPE
and a.U_VOL_NO = row_record(indx).U_VOL_NO;
IF row_record(indx).COUNTER = 1 THEN
IF new_max_enddate > row_record(indx).MAX_DATE THEN
UPDATE TABLE_B
SET MAX_DATE = new_max_enddate
WHERE U_ID = :NEW.U_ID
AND U_TYPE = :NEW.TYPE
AND U_VOL_NO = :NEW.U_VOL_NO;
END IF;
END IF;
END LOOP;
END AFTER STATEMENT;
END DATE_DIFF_CALC_A;
我评论了我正在使用的工具告诉我错误所在的代码行,如果它有帮助的话。
如果这个问题应该很容易解决,请原谅我;我对 PL/SQL 还不太熟悉,很想了解更多。
您的 temp_table 定义定义了一个 collection,称为嵌套 table。您无法访问超出集合计数属性的条目。虽然条目数是 'unlimited',但您可以通过扩展集合来增加条目数。所以在这种情况下,在你需要的错误评论之后。
row_record.extend;
row_record(row_record.count).counter := counter;
row_record(row_record.count).max_date := max_date;
...
请去掉TABLE_B.MAX_DATE%TYPE
后面的逗号
此外,
FOR UPDATE OR INSERT OF END_ON ON TABLE_A
应该是 FOR UPDATE OF END_ON OR INSERT ON
我正在尝试构建一个触发器,当 table A 的相应 end_date 更新时,它将使用最大值 end_date 列更新 Table B。
这样我就可以计算并保存我之前保存的日期与我希望从 Table A.
不断更新的最大结束日期之间的日期差异到目前为止,复合触发器似乎是一个有效的解决方案,因为我的行触发器没有完全涵盖所有用例,但是,我得到了标题中所述的错误。
完整错误:
PLS-00103: Encountered the symbol ")" when expecting one of the following: current delete exists prior
我试图找出我可能忽略的任何语法错误,但到目前为止我无法取得进展。
数据库版本似乎也正确,因为我使用的是 oracle 11g,应该支持复合触发器。
这就是前面提到的SQL:
CREATE OR REPLACE TRIGGER DATE_DIFF_CALC_A
FOR UPDATE OR INSERT OF END_ON ON TABLE_A
COMPOUND TRIGGER
TYPE temp_record IS RECORD (
COUNTER NUMBER,
B_ID TABLE_B.id%TYPE,
U_ID TABLE_B.U_ID%TYPE,
U_TYPE TABLE_B.U_TYPE%TYPE,
U_VOL_NO TABLE_B.U_VOL_NO%TYPE,
MAX_DATE TABLE_B.MAX_DATE%TYPE,
);
TYPE temp_table IS TABLE OF temp_record INDEX BY PLS_INTEGER;
row_record temp_table;
AFTER EACH ROW IS
COUNTER NUMBER;
MAX_DATE DATE;
B_ID NUMBER;
BEGIN
SELECT COUNT(*), MAX_DATE, ID
INTO COUNTER,
MAX_DATE,
B_ID
FROM TABLE_B
WHERE U_ID = :NEW.U_ID
AND U_TYPE = :NEW.TYPE AND U_VOL_NO = :NEW.U_VOL_NO GROUP BY ID, MAX_DATE;
-- Tool I am using for query tells me there is an error in this line, but there's nothing here :(
row_record(row_record.COUNT + 1).COUNTER := COUNTER;
row_record(row_record.COUNT).MAX_DATE := MAX_DATE;
row_record(row_record.COUNT).B_ID := B_ID;
row_record(row_record.COUNT).U_ID := :NEW.U_ID;
row_record(row_record.COUNT).U_TYPE := :NEW.TYPE;
row_record(row_record.COUNT).U_VOL_NO := :NEW.U_VOL_NO;
END AFTER EACH ROW;
AFTER STATEMENT IS
new_max_enddate TABLE_B.MAX_DATE%TYPE;
BEGIN
FOR indx IN 1 .. row_record.COUNT
LOOP
SELECT MAX(a.end_on)
INTO new_max_enddate
from TABLE_A a, TABLE_C C
where a.c_id = c.id and UPPER(c.place_name) not like 'XTEST%'
and a.status not in ('1', '2', '3', '4')
and a.U_ID = row_record(indx).U_ID
and a.TYPE = row_record(indx).U_TYPE
and a.U_VOL_NO = row_record(indx).U_VOL_NO;
IF row_record(indx).COUNTER = 1 THEN
IF new_max_enddate > row_record(indx).MAX_DATE THEN
UPDATE TABLE_B
SET MAX_DATE = new_max_enddate
WHERE U_ID = :NEW.U_ID
AND U_TYPE = :NEW.TYPE
AND U_VOL_NO = :NEW.U_VOL_NO;
END IF;
END IF;
END LOOP;
END AFTER STATEMENT;
END DATE_DIFF_CALC_A;
我评论了我正在使用的工具告诉我错误所在的代码行,如果它有帮助的话。
如果这个问题应该很容易解决,请原谅我;我对 PL/SQL 还不太熟悉,很想了解更多。
您的 temp_table 定义定义了一个 collection,称为嵌套 table。您无法访问超出集合计数属性的条目。虽然条目数是 'unlimited',但您可以通过扩展集合来增加条目数。所以在这种情况下,在你需要的错误评论之后。
row_record.extend;
row_record(row_record.count).counter := counter;
row_record(row_record.count).max_date := max_date;
...
请去掉TABLE_B.MAX_DATE%TYPE
此外,
FOR UPDATE OR INSERT OF END_ON ON TABLE_A
应该是 FOR UPDATE OF END_ON OR INSERT ON