SQL Server 2008 R2销售事务触发器

时间:2011-11-28 05:28:47

标签: sql sql-server sql-server-2008

我有一份作业,所以任何帮助都会对你有所帮助!

不确定我是否做得对,任何帮助都会非常感谢你!

创建一个触发器,以便最初不能输入或修改大于信用限额的销售交易。如果销售交易超过信用额度,则回滚交易。

我的代码

Create Trigger salesTransaction on Customers
For insert, update
as
--Get Credit limit
Declare @@Creditlimit money
select @@Creditlimit = CreditLimt from inserted i
Declare @@amount money
select @@amount = (p.Price * s.qtyOrdered) from inserted i
inner join Orders o
on i.CustomerNo = o.CustomerNo
inner join SalesDetail s
on s.OrderNo = o.OrderNo
inner join Products p
on (p.ManufactureID + p.ProductID) = (s.ManufactureID + s.ProductID)
where (i.CustomerNo = o.CustomerNo and o.CustomerNo = s.OrderNo and s.ManufactureID = p.ManufactureID and s.ProductID = p.ProductID)
if(@@amount > @@Creditlimit)
Begin
rollback transaction
End

我的桌子

Create Table Customers
(
CustomerNo char(4) 
Constraint ck_CustomerNoHas4positionsWithNumbers
Check(CustomerNo like'[0-9],[0-9],[0-9],[0-9]'),
Company varchar(50) not null,
CustomerRep char(3),
CreditLimt money default(20000.00),
PRIMARY KEY(CustomerNo)
)
Alter Table Customers
Add constraint fk_customerrep
FOREIGN KEY (CustomerRep) 
REFERENCES Salesreps(EmployeeNo)

Create Table Orders
(
OrderNo int,
OrderDate Date not null,
CustomerNo char(4) not null,
SalesRep char(3) not null
PRIMARY KEY(OrderNo)
)
Alter Table Orders
Add constraint fk_customerno
FOREIGN KEY (CustomerNo)
REFERENCES Customers(CustomerNo),
constraint fk_salesrep
FOREIGN KEY (SalesRep)
REFERENCES Salesreps(EmployeeNo)
Create Table SalesDetail
(
SaleDetailID int,
ManufactureID char(3) Constraint ck_ManufactureIDFromSaleDetails check(ManufactureID like'[a-z],[a-z],[a-z]') not null,
ProductID char(5) Constraint ck_ProductIDSalesDetail check(ProductID like'[0-9],[0-9],[a-z],[a-z],[a-z]') not null,
OrderNo int,
qtyOrdered int
PRIMARY KEY(SaleDetailID)
)

Alter Table SalesDetail
add FOREIGN KEY (OrderNo)
REFERENCES Orders(OrderNo)

Alter Table SalesDetail 
Add constraint fk_SalesDetails_Mid_Pid
FOREIGN KEY (ManufactureID, ProductID) 
REFERENCES Products(ManufactureID, ProductID) 

Create Table Products
(
ManufactureID char(3) 
Constraint ck_ManufactureIDifItHasLettersOnly check(ManufactureID like'[a-z],[a-z],[a-z]'),
ProductID char(5) 
Constraint ck_ProductIDhasTwoLettersAndThreeNumbers check(ProductID like'[a-z],[a-z],[0-9],[0-9],[0-9]'),
Description varchar(50) not null,
Price money not null,
QtyOnHand int not null,
PRIMARY KEY(ManufactureID, ProductID)
)

1 个答案:

答案 0 :(得分:1)

有几件事:

  • 为什么Customer上的触发器?插入(或更新)新的客户时,您不想检查这些条件 - 而是在插入新的订单时 - 没有??

  • 您的代码没有考虑到触发器将被称为每个语句一次,并且这一个语句可以很好地插入(或更新)多个订单 - 因此,Inserted伪表可以(并且会!)包含多个条目,并且您的代码不适用于多个条目....

所以我的意思是:

  • 将触发器放在Orders
  • 使其可以处理Inserted
  • 中的多行
  • 我计算订单总数超过客户CreditLimit的行数 - 如果大于零(至少有一个订单超过该限额),我回滚交易。

这是触发器代码:

CREATE TRIGGER salesTransaction ON dbo.Orders
FOR INSERT, UPDATE
AS
  --Get Credit limit
  DECLARE @Count INT

  SELECT @COUNT = COUNT(*)
  FROM Inserted i
  INNER JOIN dbo.Orders o ON i.CustomerNo = o.CustomerNo
  INNER JOIN SalesDetail s ON s.OrderNo = o.OrderNo
  INNER JOIN Products p ON p.ManufactureID = s.ManufactureID AND m.Product = s.ProductID
  INNER JOIN dbo.Customer c ON o.CustomerNo = c.CustomerNo
  WHERE (p.Price * s.qtyOrdered) > c.CreditLimit

  IF (@Count > 0)
     ROLLBACK TRANSACTION