我在执行以下触发器时遇到了一些问题:
CREATE OR REPLACE TRIGGER AFTERINSERTCREATEBILL
AFTER INSERT
ON READING
FOR EACH ROW
DECLARE
varReadNo Int;
varMeterID Int;
varCustID Varchar(10);
BEGIN
SELECT SeqReadNo.CurrVal INTO varReadNo FROM DUAL;
Select MeterID INTO varMeterID
From Reading
Where ReadNo = varReadNo;
Select CustID INTO varCustID
From Address A
Join Meter M
on A.postCode = M.postCode
Where M.MeterID = varMeterID;
INSERT INTO BILL VALUES
(SEQBILLNO.NEXTVAL, SYSDATE, 'UNPAID' , 100 , varCustID , SEQREADNO.CURRVAL);
END;
错误消息:
*原因:触发器(或用户定义的plsql函数,在中引用)
这句话)试图查看(或修改)一个表
在被解雇它的声明修改的过程中。
*动作:重写触发器(或函数),使其不读取该表。
这是否意味着我不想从表格中检索任何细节?
我认为当我在插入值时从表读取中检索数据时会出现问题:
SELECT SeqReadNo.CurrVal INTO varReadNo FROM DUAL;
Select MeterID INTO varMeterID
From Reading
Where ReadNo = varReadNo;
无论如何要解决这个问题?或者有更好的方法来做到这一点?我需要在输入表之后在表BILL中插入一个新的Read读取ReadNo需要引用的ReadNo我刚插入。
答案 0 :(得分:4)
您无法在行触发器中检索同一表中的记录。您可以使用以下命令从实际记录中访问值:new和:old(这是您的情况吗?)。然后可以将触发器重写为
CREATE OR REPLACE TRIGGER AFTERINSERTCREATEBILL
AFTER INSERT
ON READING
FOR EACH ROW
DECLARE
varCustID Varchar(10);
BEGIN
Select CustID INTO varCustID
From Address A
Join Meter M
on A.postCode = M.postCode
Where M.MeterID = :new.MeterID;
INSERT INTO BILL VALUES
(SEQBILLNO.NEXTVAL, SYSDATE, 'UNPAID' , 100 , varCustID , SEQREADNO.CURRVAL);
END;
如果需要从READING表中查询其他记录,则必须使用语句触发器,行触发器和PLSQL集合的组合。这方面的好例子是AskTom.oracle.com
答案 1 :(得分:0)
确保您对所有表格拥有必要的权限,并且可以访问您在插入内容中使用的序列。
我有一段时间没有完成Oracle,但您也可以尝试查询dba_errors(或all_errors),以便尝试获取有关您的SP未编译的原因的更多信息。
有些事情:
SELECT * FROM dba_errors WHERE owner = 'THEOWNER_OF_YOUR_SP';
答案 2 :(得分:0)
在触发器中添加异常处理,看看发生了什么,通过这样做,您可以轻松跟踪异常。
CREATE OR REPLACE TRIGGER AFTERINSERTCREATEBILL
AFTER INSERT
ON READING
FOR EACH ROW
DECLARE
varCustID Varchar(10);
BEGIN
-- your code
EXCEPTION
WHEN NO_DATA_FOUND
THEN
DBMS_OUTPUT.PUT_LINE(TO_CHAR(SQLERRM(-20299)));
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE(TO_CHAR(SQLERRM(-20298)));
END;
答案 3 :(得分:0)
我们可以组合insert和select语句
CREATE OR REPLACE TRIGGER AFTERINSERTCREATEBILL
AFTER INSERT
ON READING
FOR EACH ROW
DECLARE
varCustID Varchar(10);
BEGIN
insert into bill
values
select SEQBILLNO.NEXTVAL,
SYSDATE,
'UNPAID' ,
100 ,
CustID,SEQREADNO.CURRVAL
From Address A
Join Meter M
on A.postCode = M.postCode
Where M.MeterID = :new.MeterID;
END;
尝试上面的代码。