无法将条目插入到另一个表中,在插入后使用

问题描述 投票:0回答:1
CREATE OR REPLACE TRIGGER trg_addRentalCollection
AFTER INSERT ON contracts
FOR EACH ROW

DECLARE
    v_monthly_payment_date Date := :NEW.contractStartDate;
    v_partial_payment NUMBER(9,2);
    v_monthlyRentalFee Number(9,2);

BEGIN

    SELECT monthlyRentalFee 
    INTO v_monthlyRentalFee
    FROM stalls
    WHERE stallID = :NEW.stallID;
    
    FOR payment_rec IN 1..CEIL(:NEW.contractMonths) LOOP    
        IF payment_rec = 1 THEN
            v_partial_payment := v_monthlyRentalFee * (EXTRACT(DAY FROM LAST_DAY(:NEW.contractStartDate)) - EXTRACT(DAY FROM :NEW.contractStartDate) + 1) / EXTRACT(DAY FROM LAST_DAY(:NEW.contractStartDate));
        ELSE    
            v_partial_payment := 0; 
        END IF;
        
        INSERT INTO rentalcollection VALUES ('RC' || TO_CHAR(rentalCollection_sequence.nextVal, 'FM00000'),:NEW.contractID, :NEW.renterID, :NEW.stallID, NULL, v_partial_payment + v_monthlyRentalFee, v_monthly_payment_date, 0, 'Unpaid');
                                            
        
        v_monthly_payment_date := ADD_MONTHS(:NEW.contractStartDate, payment_rec);
        
    END LOOP;

END;
/

CREATE TABLE contracts
(
    contractID VARCHAR(15) NOT NULL, --C00001
    renterID VARCHAR(15) NOT NULL, 
    stallID VARCHAR(15) NOT NULL,
    ContractStartDate DATE,
    ContractEndDate DATE,
    contractMonths NUMBER(9,2), 
    totalContractFee NUMBER (9,2), 
    unpaidFee NUMBER (9,2),
    status VARCHAR(11),

    PRIMARY KEY (contractID, renterID, stallID),
    FOREIGN KEY (renterID) REFERENCES renters(renterID),
    FOREIGN KEY (stallID) REFERENCES stalls(stallID)
);

CREATE TABLE rentalcollection
(
    rentalCollectionID VARCHAR(15) NOT NULL,
    contractID VARCHAR(15) NOT NULL,
    renterID VARCHAR(15) NOT NULL,
    stallID VARCHAR(15) NOT NULL,
    rentalCollectionDate DATE,
    amount NUMBER(9,2),
    actualCollectionDate DATE,
    overdueFee NUMBER(9,2),
    collectionStatus VARCHAR(15) DEFAULT 'Unpaid', --paid or unpaid

    PRIMARY KEY (rentalCollectionID),
    FOREIGN KEY (contractID, renterID, stallID) REFERENCES contracts(contractID, renterID, stallID)
);

这是一条插入后记录,用于为

rentalcollection
插入多个插入,但即使创建时没有触发错误,也没有插入任何行到
rentalcollection
表中。

rentalcollection
表中有 1 个插入时,此代码预计会向
contracts
表中插入多个条目。

oracle plsql triggers
1个回答
0
投票

...但是没有记录插入到rentalcollection表中

那是因为

stalls
表中没有匹配的行,或者您输入了
contractMonths
这会阻止循环至少运行一次。

这是一个工作演示。首先,您发布的表(我删除了我没有的表的外键约束):

SQL> CREATE TABLE contracts(
  2  contractID VARCHAR(15) NOT NULL, --C00001
  3  renterID VARCHAR(15) NOT NULL,
  4  stallID VARCHAR(15) NOT NULL,
  5  ContractStartDate DATE,
  6  ContractEndDate DATE,
  7  contractMonths NUMBER(9,2),
  8  totalContractFee NUMBER (9,2),
  9  unpaidFee NUMBER (9,2),
 10  status VARCHAR(11),
 11  PRIMARY KEY (contractID,renterID, stallID)
 12  --FOREIGN KEY (renterID) REFERENCES renters(renterID),
 13  --FOREIGN KEY (stallID) REFERENCES stalls(stallID)
 14  );

Table created.

SQL> CREATE TABLE rentalcollection(
  2    rentalCollectionID VARCHAR(15) NOT NULL,
  3    contractID VARCHAR(15) NOT NULL,
  4    renterID VARCHAR(15) NOT NULL,
  5    stallID VARCHAR(15) NOT NULL,
  6    rentalCollectionDate DATE,
  7    amount NUMBER(9,2),
  8    actualCollectionDate DATE,
  9    overdueFee NUMBER(9,2),
 10    collectionStatus VARCHAR(15) DEFAULT 'Unpaid', --paid or unpaid
 11    PRIMARY KEY (rentalCollectionID),
 12    FOREIGN KEY (contractID, renterID, stallID) REFERENCES contracts(contractID, renterID, stallID)
 13  );

Table created.

我丢失了档位表和顺序;如果我想要触发器编译,我需要那个:

SQL> create table stalls as select 100 monthlyrentalfee, 1 stallid from dual;

Table created.

SQL> create sequence rentalCollection_sequence;

Sequence created.

触发;我没有修改任何东西:

SQL> CREATE OR REPLACE TRIGGER trg_addRentalCollection
  2  AFTER INSERT ON contracts
  3  FOR EACH ROW
  4
  5  DECLARE
  6  v_monthly_payment_date Date := :NEW.contractStartDate;
  7  v_partial_payment NUMBER(9,2);
  8  v_monthlyRentalFee Number(9,2);
  9
 10  BEGIN
 11
 12      SELECT monthlyRentalFee
 13      INTO v_monthlyRentalFee
 14      FROM stalls
 15      WHERE stallID = :NEW.stallID;
 16
 17      FOR payment_rec IN 1..CEIL(:NEW.contractMonths) LOOP
 18          IF payment_rec = 1 THEN
 19              v_partial_payment := v_monthlyRentalFee * (EXTRACT(DAY FROM LAST_DAY(:NEW.contractStartDate)) - EXTRACT(DAY FROM :NEW.contractStartDate) + 1) / EXTRACT(DAY FROM LAST_DAY(:NEW.contractStartDate));
 20          ELSE
 21              v_partial_payment := 0;
 22          END IF;
 23
 24          INSERT INTO rentalcollection VALUES ('RC' || TO_CHAR(rentalCollection_sequence.nextVal, 'FM00000'),:NEW.contractID, :NEW.renterID, :NEW.stallID, NULL, v_partial_payment + v_monthlyRentalFee, v_monthly_payment_date, 0, 'Unpaid');
 25
 26
 27          v_monthly_payment_date := ADD_MONTHS(:NEW.contractStartDate, payment_rec);
 28
 29      END LOOP;
 30
 31  END;
 32  /

Trigger created.

好的,我们来测试一下。插入

contracts

SQL> insert into contracts values
  2  ('a', 'b', '1', sysdate, sysdate + 2, 2, 1000, 300, 'x');

1 row created.

您期望

rentalcollection
中有一些行。我有两个,这意味着触发器似乎没问题(如果您在其他地方有正确的数据):

SQL> select * From rentalcollection;

RENTALCOLLECTIO CONTRACTID RENTERID STALLID RENTALCOL     AMOUNT ACTUALCOL OVERDUEFEE COLLECTIONSTATU
--------------- ---------- -------- ------- --------- ---------- --------- ---------- ---------------
RC00001         a          b        1                     125.81 24-DEC-23          0 Unpaid
RC00002         a          b        1                        100 24-JAN-24          0 Unpaid

SQL>
© www.soinside.com 2019 - 2024. All rights reserved.