我的数据库有表 Item、Ingredients、ItemContains、BillItem。项目由一种或多种成分“制成”,并显示在表 ItemContains (IDItem - IDIngredient - ContainingQuantity) 中。当我在 BillItem 中插入记录时,它也有 Quantity (BillItemQuantity) 字段,我希望 Trigger 或 StoredProcedure 减少成分表中 Quantity 字段的值
(IngredientQuantity = IngredientQuantity - BillItemQuantity*ContainingQuantity) ,
但问题是当 Item 包含多个成分时,不知道将 IDIngredient 放在哪里,我尝试使用临时表,但不成功。我为 Oracle 数据库编写了 PL/SQL 触发器,它可以工作,所以如果有人可以帮助将其“转换”为 SQL Server 过程或类似的东西,我将非常感激。谢谢。
create or replace
trigger ReduceQuantity
before insert on BillItem
for each row
declare
quaN BillItem.Quantity%type;
quaO BillItem.Quantity%type;
idIt integer;
idItOld integer;
type RecCon is record (IngID ItemContains.idIngredient%type, Qua ItemContains.quantity%type);
type TableQuantity is table of RecCon index by binary_integer;
i binary_integer:=0;
TabQuant TableQuantity;
begin
idIt:= :New.IDItem;
idItOld:= :Old.IDItem;
quaN := :New.Quantity;
kolS := :Old.Quantity;
for rec in (select IDIngredient, Quantity from ItemContains where IDItem = idIt) loop
TabQuant(i).IngID := rec.IDIngredient;
TabKol(i).Qua := rec.Quantity;
i:=i+1;
end loop;
if inserting then
i:=TabQuant.first;
while i<=TabQuant.last loop
update Ingredient set Quantity=Quantity-TabQuant(i).Qua*quaN where IDIngredient = TabQuant(i).IngID;
i:=TabKol.Next(i);
end loop;
end if;
end ReduceQuantity;
这是您可以在 SQL Fiddle 中运行的整个脚本。它被缩短了,但它完全可以解决这个问题。所以我想在插入新的 BillItem 时触发减少成分表中的数量(例如:BillItem 中的 2 杯卡布奇诺将减少 2 件的“浓缩咖啡”和 0.10 升的“牛奶”)
create table Item(
IDItem integer NOT NULL,
Name varchar(30) NOT NULL,
ItemType varchar(9),
Unit varchar(5) NOT NULL,
Price decimal(5,2),
CONSTRAINT item_PK PRIMARY KEY (IDItem),
CONSTRAINT item_UQ UNIQUE (Name),
CONSTRAINT item_unit_CHK CHECK (Unit in ('g', 'kg', 'ml', 'dl', 'l', 'pc')),
CONSTRAINT item_type_CHK CHECK (ItemType in ('Food', 'Beverage'))
);
create table Ingredient(
IDIngredient integer NOT NULL,
Name varchar(30) NOT NULL,
Type varchar(9),
Unit varchar(5) NOT NULL,
IngredientQuantity decimal(6,2),
CONSTRAINT ingredient_PK PRIMARY KEY (IDIngredient),
CONSTRAINT ingredient_UQ UNIQUE (Name),
CONSTRAINT ingredient_unit_CHK CHECK (Unit in ('g', 'kg', 'ml', 'dl', 'l', 'pc')),
CONSTRAINT ingredient_type_CHK CHECK (TipSastojka in ('Food', 'Beverage')),
CONSTRAINT ingredient_UQ1 CHECK(IngredientQuantity>=0)
);
create table ItemContains(
IDItem integer NOT NULL,
IDIngredient integer NOT NULL,
ContainsQuantity decimal(4,2) NOT NULL,
CONSTRAINT ItemContains_PK PRIMARY KEY (IDItem, IDIngredient),
CONSTRAINT ItemContains_FK1 FOREIGN KEY (IDItem) references Item(IDItem),
CONSTRAINT ItemContains_FK2 FOREIGN KEY (IDIngredient) references Ingredient(IDIngredient)
);
create table Bill(
IDBill integer NOT NULL,
BillDate varchar(12) NOT NULL,
TotalPrice decimal(8,2),
CONSTRAINT bill_PK PRIMARY KEY (IDBill)
);
create table BillItem(
IDBillItem integer NOT NULL,
IDBill integer NOT NULL,
IDItem integer NOT NULL,
BillItemQuantity decimal(3,1),
CONSTRAINT billitem_PK PRIMARY KEY (IDBillItem),
CONSTRAINT billitem_FK1 FOREIGN KEY (IDItem) references Item(IDItem),
CONSTRAINT billitem_FK2 FOREIGN KEY (IDBill) references bill(IDBill)
);
Insert into Ingredient values(1, 'Amstel draft', 'Beverage', 'l', 100);
Insert into Ingredient values(2, 'Espresso coffee', 'Beverage', 'pc', 275);
Insert into Ingredient values(3, 'Milk', 'Beverage', 'l', 90);
Insert into Item values(1, 'Amstel - small', 'Beverage', 'l', 5);
Insert into Item values(2, 'Amstel - large', 'Beverage', 'l', 7);
Insert into Item values(3, 'Espresso', 'Beverage', 'pc', 4.5);
Insert into Item values(4, 'Cappuccino', 'Beverage', 'pc', 5.5);
Insert into ItemContains(IDItem, IDIngredient,ContainsQuantity) values(1, 1, 0.3);
Insert into ItemContains(IDItem, IDIngredient,ContainsQuantity) values(2, 1, 0.5);
Insert into ItemContains(IDItem, IDIngredient,ContainsQuantity) values(3, 2, 1);
Insert into ItemContains(IDItem, IDIngredient,ContainsQuantity) values(4, 2, 1);
Insert into ItemContains(IDItem, IDIngredient,ContainsQuantity) values(4, 3, 0.05);
insert into Bill values(1, '12-jun-2013', null);
Insert into BillItem(IDBillItem, IDBill, IDItem, BillItemQuantity) values(1, 1, 1, 3);
Insert into BillItem(IDBillItem, IDBill, IDItem, BillItemQuantity) values(2, 1, 2, 1);
Insert into BillItem(IDBillItem, IDBill, IDItem, BillItemQuantity) values(3, 1, 3, 1);
Insert into BillItem(IDBillItem, IDBill, IDItem, BillItemQuantity) values(4, 1, 4, 2);
CREATE VIEW ItemsIngredientsView AS
select sa.IDItem as "ID Item", art.Name as "Item name", sa.ContainsQuantity as "Quantity", s.Unit as "Unit", s.IDIngredient as "ID Ingredient", s.Name as "Ingredient name" from ItemContains sa left join Ingredient s on sa.IDIngredient=s.IDIngredient left join Item art on art.IDItem = sa.IDItem;
CREATE VIEW BillView AS
select r.IDBill as "Bill", sr.IDItem as "ID Item", art.Name as "Item Name", sr.BillItemQuantity as "Quantity", art.Price as "Price" from Bill r right join BillItem sr on r.IDBill=sr.IDBill left join Item art on sr.IDItem = art.IDItem;
CREATE VIEW BillTotalPriceView AS
select sum(sr.BillItemQuantity*art.Price) as "TotalPrice" from Bill r right join BillItem sr on r.IDBill=sr.IDBill left join Item art on sr.IDItem = art.IDItem;