2016-01-16 3 views
1

В чем проблема с переменной @temp?как вызвать функцию внутри триггера?

create function dbo.getNumOfReviews2 (@email varchar(40)) 
returns int 
as begin 
declare @numOfReviews int 
    select @numOfReviews = count(*) 
    from dbo.Reviews 
    where email = @email 
    group by Email 
return @numOfReviews 
end 

CREATE TRIGGER setDiscount 
ON dbo.[Contains] 
FOR INSERT 
AS 
    DECLARE @OrderID int 
    DECLARE @ProductID int 
    DECLARE @Size VarChar(15) 
    DECLARE @temp int 
    IF CURSOR_STATUS('global','C_CURSOR')>=-1 
     BEGIN 
     DEALLOCATE C_CURSOR 
     END 
    DECLARE C_CURSOR CURSOR 
    FOR SELECT ProductID,OrderID,Size 
    FROM INSERTED 
    BEGIN 
     OPEN C_CURSOR 
     FETCH NEXT FROM C_CURSOR INTO @ProductID,@OrderID,@Size 
     WHILE (@@FETCH_STATUS=0) 
      BEGIN 
       @temp = dbo.getNumOfReviews2(select BillingEmail from dbo.Orders where [email protected]) 
       IF (SELECT COUNT(*) 
        FROM dbo.[Contains] 
        WHERE OrderID = @OrderID) > 5 or (SELECT sum(Quantity) FROM dbo.[Contains] WHERE [email protected]) > 10 or 
        (@temp)> 5 
         UPDATE [Contains] 
         SET [Savings%] = [Savings%] + 0.05 
         WHERE OrderID = @OrderID and ProductID = @ProductID and Size = @Size 
       FETCH NEXT FROM C_CURSOR INTO @ProductID,@OrderID,@Size 
      END 

    END 

ответ

2

Использование select для вызова скалярной функции

правильный способ сделать это было бы

select @temp = dbo.getNumOfReviews2(BillingEmail) 
from dbo.Orders 
where [email protected] 

Примечание: Не рекомендуется писать большую логику внутри триггера. Триггеры должны быть простыми и быстрыми, иначе ваши операции DML будут медленными. Кроме того, вы использовали CURSOR, которого следует избегать любой ценой. Перепишите код с использованием подхода на основе SET.

Вот SET подход, опирающийся код

;WITH cte 
    AS (SELECT c1.orderid 
     FROM dbo.[contains] c1 
       INNER JOIN inserted i1 
         ON i1.orderid = c1.orderid 
     GROUP BY orderid 
     HAVING Count(*) > 5 
       OR Sum(quantity) > 5 
       OR @temp > 5) 
UPDATE C 
SET [savings%] = [savings%] + 0.05 
FROM [contains] C 
     INNER JOIN inserted I 
       ON I.orderid = C.orderid 
        AND I.productid = C.productid 
        AND I.size = C.size 
        AND EXISTS (SELECT 1 
           FROM cte c1 
           WHERE c1.orderid = c.orderid) 
Смежные вопросы