SQL Server,BIG挑战,更新触发器或程序(无论什么工作)

时间:2013-07-18 13:44:57

标签: sql sql-server stored-procedures triggers

我有两张桌子

EmpAssignment
 EmpId | LocationNo |其他不相关的

MonthlyTransaction
 EmpID |支付代码| InputAmount |和其他不相关的

我想要一个触发器(或任何可行的),如果:

使用值104或105插入或更新某个EmpID的

1。 EmpAssignment.LocationNo ,然后 MonthlyTransaction.Paycode MonthlyTransaction.InputAmount 分别插入值35和12。

插入某个 EmpID

2。 EmpAssignment.LocationNO ,更新为值204或205,然后 MonthlyTransaction.Paycode < / em>和 MonthlyTransaction.InputAmount 分别插入值36和15。

现在更多的技巧部分, MonthlyTransaction.EmpID 是一个外键,这意味着每个 EmpID 的行数多于行,而插入,更新只会影响支付代码为35或36且输入安装数为12或15的 EmpID 行。

如果上面没有包含Paycode和InputAmount的特定 EmpID 的行,则触发器应插入否则更新。

我到目前为止的地方:

CREATE TRIGGER tr_ProvincialAllowance
ON [dbo].[Empassignment]
FOR INSERT, UPDATE
AS
UPDATE M
SET Paycode = 35, InputAmnt = 12
FROM MonthlyTransaction AS M
INNER JOIN inserted E
ON E.EmpId = M.EmpId AND E.LocationNo = 104

上述触发器的一个问题是,它将更新所有 MonthlyTransaction。 EmpID paycode和inputAmnt 35和12

我知道这有很多要问,但请有人救我。

2 个答案:

答案 0 :(得分:1)

首先使用UPDATE,然后使用INSERT所有未找到的内容,这样的内容(仅显示Paycode = 35,InputAmnt = 12,LocationNo = 104)。

CREATE TRIGGER tr_ProvincialAllowance
ON [dbo].[Empassignment]
FOR INSERT, UPDATE
AS
UPDATE M
SET InputAmnt = 12
FROM MonthlyTransaction AS M
INNER JOIN inserted E
    ON E.EmpId = M.EmpId AND E.LocationNo = 104 AND Paycode = 35

INSERT M
SET EmpId = E.EmpID, InputAmnt = 12, Paycode = 35
FROM inserted E
LEFT JOIN MonthlyTransaction AS M
    ON E.EmpId = M.EmpId AND E.LocationNo = 104 AND Paycode = 35
WHERE M.EmpID  NULL

如果您使用SQL 2008或更高版本,则可以使用MERGE代替UPDATEINSERT

答案 1 :(得分:0)

这是你的触发器。使用CTE设置Source和Target的条件,然后简单的MERGE语句可以完成其余的工作。

CREATE TRIGGER tr_ProvincialAllowance
ON [dbo].[Empassignment]
AFTER INSERT, UPDATE
AS
BEGIN

    WITH CTE_Target AS 
    (
        SELECT m.* 
        FROM MonthlyTransaction m
         INNER JOIN INSERTED e ON e.EmpID = m.EmpID
        WHERE m.PayCode IN (35,36)
         AND m.InputAmount IN (12,15)   
    )
    ,CTE_Source AS
    (
        SELECT i.empID
            ,i.LocationNo
            ,CASE WHEN i.LocationNo IN (104,105) THEN 35 ELSE 36 END AS PayCode
            ,CASE WHEN i.LocationNo IN (104,105) THEN 12 ELSE 15 END AS InputAmount
        FROM INSERTED i
        WHERE i.LocationNo  IN (104,105,204,205)
    )  
    MERGE CTE_Target t
    USING CTE_Source s
    ON s.EmpID = t.EmpID
    WHEN MATCHED THEN 
        UPDATE SET t.PayCode = s.PayCode, T.InputAmount = s.InputAmount
    WHEN NOT MATCHED THEN 
        INSERT (EmpID, PayCode,InputAmount) 
        VALUES (s.EmpID, s.PayCode, s.InputAmount);
END

<强> SQLFiddle DEMO