SQL Server删除触发器返回select语句,如何捕获该数据?

时间:2015-02-19 18:40:54

标签: sql-server triggers sql-server-2012

在桌面上,有一个执行某些操作的删除触发器,然后在最后执行一个select语句,所以当你做类似的事情......

delete from mytable where id=1

它返回一个记录集。

有没有办法将该记录集的结果保存到临时表或其他内容?我试过这样的事情:

declare @temptable table (returnvalue int);
insert into @temptable (returnvalue)
delete from mytable where id=1;

但显然语法不起作用。

2 个答案:

答案 0 :(得分:1)

那么,

我无法想象您需要使用返回记录集的触发器返回要删除的行的记录集的情况。但我不是来判断你的要求。

好吧,您可以使用OUTPUT显示将被排除的行数据,并将此数据输入临时表。请按照以下示例。

但是您应该知道:SQL Server不保证DML语句使用OUTPUT子句处理和返回哪些行的顺序。由应用程序来包含WHERE子句适当的que可以保证所需的语义,或者理解que当多行可能有资格进行DML操作时,可以按顺序保证。以下示例使用子查询,并假设唯一性是列的一个特征,以便将DatabaseLogID置于所需的排序语义中。请参阅link

示例:

CREATE TABLE Person
(
PersonID int,
LastName varchar(255),
FirstName varchar(255)
);
GO

--DECLARE @MyTablePerson TABLE
--(
--    PersonID int,
--    LastName varchar(255),
--    FirstName varchar(255)
--);
--GO

--CREATE TRIGGER TRG_DLT_Person
--ON Person
--INSTEAD OF DELETE
--AS
--BEGIN

     -- Some code you want to do before delete

--     DELETE Person
--     FROM DELETED D
--END
--GO

insert into Person
(PersonID,
LastName,
FirstName)
values
(1,
'Kilmister',
'Lemmy');
GO

insert into Person
(PersonID,
LastName,
FirstName)
values
(2,
'Gilmour',
'David');
GO

insert into Person
(PersonID,
LastName,
FirstName)
values
(3,
'Rose',
'Axl');
GO

insert into Person
(PersonID,
LastName,
FirstName)
values
(4,
'Bullock',
'Sandra');
GO

-

select * from Person;
GO

delete from Person
--output deleted.* INTO @MyTablePerson
output deleted.*
WHERE PersonID = 4 OR PersonID = 2;
GO

select * from Person;
GO

select * from @MyTablePerson;
GO

我将示例显示在此环境中,但在此环境中认为临时表不支持。

SQL Fiddle

答案 1 :(得分:1)

无论这是一种不好的做法,因为任何与桌子交互的人都很难知道它会发生并且在它发生时处理它,并且不管它是否有可能捕获,一个非常可靠的理由<来自触发器的em> not 返回结果集是因为SQL Server的下一个版本之一将禁止这样做,因此您无论如何都必须重新编码该功能。 disallow results from triggers Server Configuration Option个状态的MSDN页面:

  

重要

     

此功能将在下一版本的Microsoft SQL Server中删除。请勿在新的开发工作中使用此功能,并尽快修改当前使用此功能的应用程序。我们建议您将此值设置为1。

如果您只是从触发器返回SELECT IdField FROM deleted;之类的内容,那么您应该(确实需要)使用OUTPUT子句代替。

话虽如此,做以下事情将会做你想做的事:

CREATE TABLE #TempResults
(
  ReturnValue INT
);

INSERT INTO #TempResults (ReturnValue)
  EXEC('DELETE FROM mytable WHERE id = 1;');

您可以使用以下方法进行测试:

SET NOCOUNT ON;
IF (OBJECT_ID('dbo.DeleteTriggerWithResults') IS NOT NULL)
BEGIN
  DROP TABLE dbo.DeleteTriggerWithResults;
END;

CREATE TABLE dbo.DeleteTriggerWithResults
(
  Col1 INT NOT NULL IDENTITY(1, 1),
  Col2 DATETIME DEFAULT (GETDATE())
);
GO
CREATE TRIGGER dbo.tr_DeleteTriggerWithResults_d
ON dbo.DeleteTriggerWithResults
AFTER DELETE
AS
BEGIN

  SELECT Col1
  FROM deleted;

END;
GO

INSERT INTO dbo.DeleteTriggerWithResults DEFAULT VALUES;
GO 30

SELECT * FROM dbo.DeleteTriggerWithResults;

然后运行测试:

DECLARE @TempResults TABLE (Col1 INT);

INSERT INTO @TempResults (Col1)
EXEC('
    DELETE TOP (10)
    FROM  dbo.DeleteTriggerWithResults;
');

SELECT * FROM @TempResults;

返回:

  

Col1中
  -------
  10个
  9
  8
  7
  6
  5
  4
  3
  2
  1