如何在SQL Server中的触发器中检查和更新表

时间:2018-12-05 08:14:29

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

嗨,我有一张桌子,上面有这样的数据...

A     B    C     D    E 
100  A1  Hard  Dece  100
100  A1  Hard  Jan   200
100  A1  SOFT  Jan   200
200  A2  Hard  Dec   250
200  A2  SOFT  Jan   300
----------------------------

然后,当在此表上执行插入或更新操作时,我需要执行一个触发器,并且数据应如下所示

A    B   C     F
100  A1 Hard   Dece:100;Jan:200
100  A1 SOFT   Jan:200
200  A2 Hard   Dec:250
------------------------

我已经创建了一个如下所示的触发器

ALTER TRIGGER [dbo].[trgInsert9] ON [roll].[dbo].[testing]
after INSERT,Update
AS
Declare @Counter int=0
Declare @max int
Declare @re int
select *  into  #t13  from (select A,B,C,[D] + ':' + cast([E] as varchar) as Common  from [roll].[dbo].[testing]) as X
select * into #t24 from (
SELECT t2.A,t2.B,t2.C,  
STUFF((SELECT ';' + CAST(Common AS varchar) 
FROM #t13 t1  where t1.A =t2.A and t1.B=t2.B and t1.C=t2.C
FOR XML PATH('')), 1 ,1, '') AS List
FROM #t13 t2
GROUP BY t2.A,t2.B,t2.C) as XT
SET @max=(select count(A) from #t24)
while(@Counter<@max)
BEGIN
if exits(select count(t11.A) from Test123 t11 left join #t24 f on t11.A=f.A 
 where t11.A=f.A and t11.B=f.B and t11.C=f.C
and t11.ValueList=f.ValueList)
  Begin
update Test123 set Test123.ValueList=t4.ValueList from #t24 t4
where
 Test123.A=t4.A and Test123.B=t4.B and Test123.C=t4.C
END
ELSE
BEGIN
insert into Test123
select * from #24 t8
END
SET @Counter=@Counter+1
END
drop table #t13
drop table #t24

但是我没有得到正确的结果,例如,如果插入了第一个,然后没有更新,则意味着它正在将其添加到下一个,如下所示:-

A   B  C  F
100 A1 Hard Dece:100
100 A1  Hard Dece:100;jan:200
------------------------------

但是在临时表中,我得到了正确的结果,当我尝试插入或更新时,出现了问题,请帮助我。

1 个答案:

答案 0 :(得分:1)

您的触发器完全乱码。首先,您应该学习如何格式化sql脚本。我在SO中找到了这个SQL Formatting standards标题。请阅读。关于格式化没有特定规则,但主要规则是您的查询应可读!

此外,您不应该对触发器进行大量计算。它会影响sql性能。

在我的拙见中; DELETE,然后INSERT的相关行(到第二张表)比IF EXISTS()-> UPDATEELSE-> INSERT更好处理。

我已经为您创建了示例,您可以检查它:

--DROP TABLE Testing;

CREATE TABLE Testing
(
     A  INT
    ,B  VARCHAR(100)
    ,C  VARCHAR(100)
    ,D  VARCHAR(100)
    ,E  INT
);

--DROP TABLE Test123;

CREATE TABLE Test123
(
     A  INT
    ,B  VARCHAR(100)
    ,C  VARCHAR(100)
    ,F  VARCHAR(MAX)
);


--DROP TRIGGER [dbo].[trgInsert9] ;

CREATE TRIGGER [dbo].[trgInsert9] 
    ON /*[roll].*/[dbo].[Testing]
AFTER INSERT,UPDATE,DELETE
AS

DELETE FROM [dbo].Test123
WHERE EXISTS (
                SELECT 1
                FROM INSERTED I
                WHERE Test123.A = I.A
                AND Test123.B = I.B
                AND Test123.C = I.C
                )

DELETE FROM [dbo].Test123
WHERE EXISTS (
                SELECT 1
                FROM DELETED I
                WHERE Test123.A = I.A
                AND Test123.B = I.B
                AND Test123.C = I.C
                )

SELECT DISTINCT A,B,C 
INTO #List 
FROM INSERTED

INSERT INTO [dbo].Test123(A,B,C,F)
SELECT A,B,C,STUFF((SELECT ';' + CAST(D AS varchar) +':'+ CAST(E AS varchar) 
                    FROM Testing T  
                    WHERE T.A =L.A 
                    AND T.B=L.B
                    AND T.C=L.C
                    FOR XML PATH('')), 1 ,1, '') 
FROM #List L
GO

DELETE FROM Testing;
INSERT INTO Testing
VALUES
 (100,'A1','Hard','Dece',100)
,(100,'A1','Hard','Jan ',200)
,(100,'A1','SOFT','Jan ',200)
,(200,'A2','Hard','Dec ',250)
,(200,'A2','SOFT','Jan ',300);

SELECT * FROM Testing
SELECT * FROM Test123