如果在INSERT语句中没有赋值,是否需要在触发器中包含GENERATED ALWAYS AS?

时间:2014-11-01 18:13:04

标签: sql oracle plsql triggers

当INSERT语句仅包含NoSerieVehicule,ClientID,ModeFinCd,EmplID,DateVente,PrixVenteVehicule时,我尝试执行将初始化VenteID,CoutTotalOption,TauxEscompteSaisonnier,IndicateurFidelite,TauxEscompteFidelite,TaxeProvCourante,TaxeFedCourante的PLSQL触发器。 Here's an image of said table.

表的定义:

CREATE TABLE AU_Ventes (
VenteID                 NUMBER(7) NOT NULL,
NoSerieVehicule         CHAR(11) NOT NULL,
ClientID                NUMBER(7) NOT NULL,
ModeFinCd               CHAR(2) NOT NULL, 
EmplID                  NUMBER(7) NOT NULL,
TauxEscompteSaisonnier  NUMBER(5,4),
DateVente               DATE 
                        DEFAULT SYSDATE
                        NOT NULL,
DateFinGarantie         AS (ADD_MONTHS(DateVente,60)),
PrixSuggere             NUMBER(8,2),
PrixVenteVehicule       NUMBER(8,2) NOT NULL,
EscompteSaisonnier      NUMBER(8,2),
IndicateurFidelite      CHAR(1),
TauxEscompteFidelite    NUMBER(5,4),
CoutVehiculeEscompte    NUMBER(8,2) GENERATED ALWAYS AS (PrixVenteVehicule * (TauxEscompteFidelite + TauxEscompteSaisonnier) + EscompteSaisonnier),
CoutTotalOption         NUMBER(8,2) NOT NULL,
TotalVenteTaxable       NUMBER(8,2) GENERATED ALWAYS AS (PrixVenteVehicule - (PrixVenteVehicule * (TauxEscompteFidelite + TauxEscompteSaisonnier) + EscompteSaisonnier) + CoutTotalOption ),
TaxeFedCourante         NUMBER(8,2) GENERATED ALWAYS AS ((PrixVenteVehicule - (PrixVenteVehicule * (TauxEscompteFidelite + TauxEscompteSaisonnier) + EscompteSaisonnier) + CoutTotalOption ) * 0.05), 
TaxeProvCourante        NUMBER(8,2) GENERATED ALWAYS AS (((PrixVenteVehicule - (PrixVenteVehicule * (TauxEscompteFidelite + TauxEscompteSaisonnier) + EscompteSaisonnier) + CoutTotalOption ) * 1.05 ) * 0.095),
TotalTaxes              NUMBER(8,2) GENERATED ALWAYS AS ((PrixVenteVehicule - (PrixVenteVehicule * (TauxEscompteFidelite + TauxEscompteSaisonnier) + EscompteSaisonnier) + CoutTotalOption )*(0.05+(1.05*0.095))),
GrandTotalVente         NUMBER(8,2) GENERATED ALWAYS AS ((PrixVenteVehicule - (PrixVenteVehicule * (TauxEscompteFidelite + TauxEscompteSaisonnier) + EscompteSaisonnier) + CoutTotalOption )*(1+0.05+(1.05*0.095))),
CONSTRAINT PK_VenteID PRIMARY KEY (VenteID),
CONSTRAINT FK_NoSerieVehicule FOREIGN KEY (NoSerieVehicule) REFERENCES AU_Vehicules (NoSerieVehicule),
CONSTRAINT FK_ClientID FOREIGN KEY (ClientID) REFERENCES AU_Clients (ClientID),
CONSTRAINT FK_ModeFinCd FOREIGN KEY (ModeFinCd) REFERENCES AU_ModesFinancements (ModeFinCd),
CONSTRAINT CK_PrixVenteVehicule   CHECK (PrixVenteVehicule >= 0),
CONSTRAINT CK_EscompteSaisonnier  CHECK (EscompteSaisonnier >= 0),
CONSTRAINT CK_CoutTotalOption     CHECK (CoutTotalOption >= 0));

到目前为止,这是我的PLSQL代码。

CREATE OR REPLACE TRIGGER TR_06InsVente
BEFORE INSERT ON AU_Ventes
FOR EACH ROW
WHEN (:new.VenteID IS NULL) --IS THIS NEEDED?
DECLARE

v_VenteID = AU_Ventes.VenteID%TYPE;
v_TauxEscompteSaisonnier = AU_Ventes.TauxEscompteSaisonnier%TYPE;
v_IndicateurFidelite = AU_Ventes.IndicateurFidelite%TYPE;
v_TauxEscompteFidelite = AU_Ventes.TauxEscompteFidelite%TYPE;
v_TaxeFedCourante = AU_Ventes.TaxeFedCourante%TYPE;
v_TaxeProvCourante = AU_Ventes.TaxeProvCourante%TYPE;
v_CoutTotalOption = AU_Ventes.CoutTotalOption%TYPE;

BEGIN

--VenteId
SELECT SEQ_VenteId.NEXTVAL INTO v_VenteID FROM DUAL;

:new.VenteID := v_VenteID;

--TauxEscompteSaisonnier
SELECT AU_Modeles.TauxEscompteSaisonnier INTO v_TauxEscompteSaisonnier
FROM AU_Vehicules INNER JOIN AU_Modeles
ON (AU_Vehicules.ModeCd = au_modeles.modecd)
WHERE ((AU_Vehicules.NoSerieVehicule = :new.NoSerieVehicule) AND 
(datefinescomptesaisonnier >= sysdate))

:new.TauxEscompteSaisonnier := v_TauxEscompteSaisonnier;

--IndicateurFidelite
SELECT AU_Clients.IndicateurFidelite INTO v_IndicateurFidelite
FROM AU_Clients 
WHERE (AU_Clients.ClientID = :new.ClientID)

:new.IndicateurFidelite := v_IndicateurFidelite;

--TauxEscompteFidelite
SELECT AU_Modeles.TauxEscompteFidelite INTO v_TauxEscompteFidelite
 FROM AU_Modeles INNER JOIN AU_Vehicules
 ON AU_Modeles.ModeCd = AU_Vehicules.ModeCd
 WHERE ((AU_Vehicules.NoSerieVehicule = :new.NoSerieVehicule) AND
 ('1' = (SELECT AU_Clients.IndicateurFidelite FROM AU_Clients 
 WHERE AU_Clients.ClientID = :new.ClientID)))

:new.v_TauxEscompteFidelite := v_TauxEscompteFidelite;

--v_TaxeFedCourante what do I do with this since it is "GENERATED ALWAYS AS"
--v_TaxeProvCourante what do I do with this since it is "GENERATED ALWAYS AS"
--v_CoutTotalOption not sure about this either HARDCODED in inserts from teacher


EXCEPTION
WHEN OTHERS THEN
enregistrer_erreur();
RAISE;
END;
/

基本上我不明白的是,我是否需要在PLSQL中初始化colums值,如果是,我该怎么做?既然它是虚拟列?

很抱歉,如果变量名称是法语,希望您仍能理解我的问题。

提前致谢。

1 个答案:

答案 0 :(得分:2)

我不完全确定我理解你提出的问题。

您无法将值分配给表中的虚拟列。 Oracle自动生成值。您可以忽略触发器中的这些列。

我希望这是一个家庭作业问题,因为你的评论引用了“老师”。如果没有,您的数据模型看起来很可疑 - 由于您从多个不同的表复制数据,因此您的表似乎严重非规范化。这实际上从来都不是一个好主意,因为保持所有数据同步是非常非常困难的。