2011-11-28 44 views
1

我有一個任務,所以任何幫助將有助於很多謝謝你!SQL Server 2008 R2銷售交易觸發器

不知道如果我做對了任何幫助將是偉大的謝謝你!

創建一個觸發器,以便無法初始輸入或修改大於信用額度的銷售交易。如果銷售交易超過信用額度,請回滾交易。

我的代碼

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) 
) 
+0

當你運行它 - 它做你找什麼?如果不是:它有什麼作用?你在任何地方遇到錯誤嗎? –

+0

這些行在這裏:如果你的'Inserted'僞表具有多個'select @@ Creditlimit = CreditLimt from insert i'和'select @@ amount =(p.Price * s.qtyOrdered)from insert i'將會失敗一排......可能!觸發器運行**每個語句**(可以插入多行) - ** NOT **每行一次...... –

+0

您是否意識到這種情況,on(p.ManufactureID + p.ProductID )=(s.ManufactureID + s.ProductID)',可能(並且可以說會)將你的查詢設置爲non [sargable](http://en.wikipedia.org/wiki/Sargable)?真的有必要以這種方式加入表格嗎?或者,這種表達式只是因爲你有點懶得寫下這個結果而已:'on p.ManufactureID = s.ManufactureID and p.ProductID = s.ProductID'? –

回答

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 
+1

謝謝!非常 – user996502