我试图在Oracle 8i中创建一个包含3个表的小型数据库,并在它们上面创建两个触发器。 这是数据库模式:
我创建了表格:
CREATE TABLE SYSTEM.Invoices(
invoice_id NUMBER NOT NULL,
invoice_body_xml CLOB NOT NULL,
insertTS DATE NOT NULL,
modifyTS DATE,
PRIMARY KEY (invoice_id))
TABLESPACE SYSTEM;
CREATE TABLE SYSTEM.Invoice_Statuses(
invoice_id NUMBER NOT NULL,
status NVARCHAR2(15) NOT NULL,
status_details CLOB,
transaction_id NVARCHAR2(50),
transaction_index NUMBER,
request_id NVARCHAR2(50),
insertTS DATE NOT NULL,
CONSTRAINT from_statuses_to_invoices
FOREIGN KEY(invoice_id)
REFERENCES SYSTEM.INVOICES(invoice_id))
TABLESPACE SYSTEM;
CREATE TABLE SYSTEM.Open_Invoices(
invoice_id NUMBER NOT NULL,
invoice_body_xml CLOB NOT NULL,
status NVARCHAR2(15) NOT NULL,
transaction_id NVARCHAR2(50),
transaction_index NUMBER,
insertTS DATE NOT NULL,
CONSTRAINT from_open_to_invoices
FOREIGN KEY(invoice_id)
REFERENCES SYSTEM.INVOICES(invoice_id))
TABLESPACE SYSTEM;
我需要的TRIGGERS:
CREATE OR REPLACE TRIGGER after_invoice_insert
AFTER INSERT
ON SYSTEM.INVOICES
FOR EACH ROW
BEGIN
INSERT INTO SYSTEM.INVOICE_STATUSES
(INVOICE_ID,
STATUS,
INSERTTS)
VALUES
(
:NEW.invoice_id,
n'NEW',
SYSDATE);
END;
另一个:
CREATE OR REPLACE TRIGGER after_invoice_statuses_insert
AFTER INSERT
ON SYSTEM.INVOICE_STATUSES
FOR EACH ROW
DECLARE
body_xml CLOB;
BEGIN
SELECT SYSTEM.INVOICES.invoice_body_xml INTO body_xml FROM SYSTEM.INVOICES WHERE SYSTEM.INVOICES.invoice_id = :NEW.invoice_id;
INSERT INTO SYSTEM.OPEN_INVOICES
(INVOICE_ID,
INVOICE_BODY_XML,
STATUS,
TRANSACTION_ID,
TRANSACTION_INDEX,
INSERTTS)
VALUES
(
:NEW.invoice_id,
body_xml,
:NEW.status,
:NEW.transaction_id,
:NEW.transaction_index,
SYSDATE);
END;
如您所见,在OPEN_INVOICES表中,我需要来自INVOICES表的body_xml,这就是我想用select创建body_xml的原因。
答案 0 :(得分:3)
你有一个触发器,它会在插入INVOICES
后触发。这会触发插入INVOICE_STATUSES
。
你还有一个触发器,它会在INVOICE_STATUSES
后插入,但是在这个触发器中你试图从表INVOICES
中选择 - 你得到错误。
在任何触发器中将您的声明和所有 DML视为一个命令。在其中插入任何数据时,无法选择表。
您应该将所有逻辑放入存储过程并执行该过程。
答案 1 :(得分:0)
如果您需要通过触发器完成此操作,那么最好的方法是将with
存储在invoice_body_xml
中,并在INVOICE_STATUSES
的触发器中填充它:
INVOICES
答案 2 :(得分:0)
我建议你不要试图折叠,转动和毁坏一堆触发器来完成所需的INSERT,SELECT等,我建议您编写一个程序来创建类似于以下的发票:
CREATE OR REPLACE PROCEDURE CREATE_INVOICE
(pinInvoice_id IN NUMBER,
pinInvoice_body_xml IN CLOB)
IS
BEGIN
INSERT INTO INVOICES
(INVOICE_ID,
INVOICE_BODY,
INSERTTS)
VALUES
(pinInvoice_id,
pinInvoice_body_xml,
SYSDATE);
INSERT INTO INVOICE_STATUSES
(INVOICE_ID,
STATUS,
INSERTTS)
VALUES
(pinInvoice_id,
n'NEW',
SYSDATE);
INSERT INTO OPEN_INVOICES
(INVOICE_ID,
INVOICE_BODY_XML,
STATUS,
TRANSACTION_ID,
TRANSACTION_INDEX,
INSERTTS)
VALUES
(pinInvoice_id,
pinInvoice_body_xml,
n'NEW',
???, -- don't know where this comes from
???, -- don't know where this comes from
SYSDATE);
END CREATE_INVOICE;
您可能仍希望使用触发器来设置INSERTTS和MODIFYTS等字段。
在执行此操作时,我发现需要设置OPEN_INVOICES中的几个字段,但是在初始化时没有(据我所知)。这可能是您想要研究的内容。
祝你好运。