【发布时间】:2014-08-07 13:10:48
【问题描述】:
我真的希望有人可以帮助我...
我有一个触发器来处理向表中插入新记录。正如您将在下面看到的,此触发器将一条记录插入到另一个表中,该表依次在该表上执行一个触发器,该触发器调用一个存储过程(我尝试在触发器本身内执行此操作,但失败并且难以测试哪里出了问题,所以我把它搬到了它自己的小单元里。)
在存储过程中,调用从 Active Directory 数据库 (ADSI) 中提取信息并更新新插入的记录。但是,这就是触发器调用时失败的地方。当我通过简单地执行它并传递要更新的记录来调用它时,它工作得很好......有人能指出我正确的方向吗?请!!!
在 YYY 中触发 #1
USE [YYY]
GO
/****** Object: Trigger [dbo].[NewCustodian] Script Date: 08/04/2014 09:38:11 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER TRIGGER [dbo].[NewCustodian]
ON [YYY].[dbo].[Custodians]
AFTER INSERT
AS BEGIN
SET NOCOUNT ON;
DECLARE @CaseID varchar(20);
DECLARE DBcursor CURSOR FOR
SELECT [XXX].[dbo].[tblCase].CaseID from [XXX].[dbo].[tblCase] Where [XXX].[dbo].[tblCase].SQLSVR_Case_ID = 'YYY';
Open DBcursor; FETCH DBCursor into @CaseID;
CLOSE DBcursor; DEALLOCATE DBcursor;
DECLARE @NAME varchar(255);
DECLARE @TAG varchar(255);
SELECT @NAME = name FROM inserted;
SELECT @TAG = tag FROM inserted;
IF NOT EXISTS (Select eID from [XXX].[dbo].[tblNames]
WHERE eID = @TAG and CaseID = @CaseID)
BEGIN
INSERT INTO [XXX].[dbo].[tblNames] (CaseID, Name, eID)
Values (@CaseID, @NAME, @Tag);
END
END
XXX 中的触发器 #2
USE [XXX]
GO
/****** Object: Trigger [dbo].[tblNames_New] Script Date: 08/04/2014 08:56:43 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:
-- Create date:
-- Description:
-- =============================================
ALTER TRIGGER [dbo].[tblNames_New]
ON [XXX].[dbo].[tblNames]
AFTER INSERT
AS BEGIN
SET NOCOUNT ON;
DECLARE @NamesID varchar(10)
DECLARE @TAG varchar(10);
DECLARE @return_value int
SELECT @NamesID = namesID FROM inserted
EXEC dbo.UpdateNames @NamesID;
End
存储过程:
USE [XXX]
GO
/****** Object: StoredProcedure [dbo].[UpdateNames] Script Date: 08/04/2014 08:14:52 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:
-- Create date:
-- Description:
-- =============================================
ALTER PROCEDURE [dbo].[UpdateNames]
@NamesID int
AS
BEGIN
SET FMTONLY OFF;
SET NOCOUNT ON;
DECLARE @eID varchar(10);
DECLARE @TAG varchar(10);
DECLARE @SQL nvarchar(555);
DECLARE @DBresults as table (
eID nvarchar(100),
mobile nvarchar(100),
mail nvarchar(100),
phone nvarchar(100),
name nvarchar(50),
legacyExchangeDN nvarchar(100),
Title nvarchar(100),
homeDirectory nvarchar(100));
DECLARE @mobile nvarchar(100)
DECLARE @mail nvarchar(100)
DECLARE @phone nvarchar(100) = 'Error'
DECLARE @name nvarchar(100)
DECLARE @legacyExchangeDN nvarchar(100)
DECLARE @Title nvarchar(100) = 'Error'
DECLARE @homeDirectory nvarchar(100)
SET @eID = (Select eID from [XXX].[dbo].[tblNames] Where NamesID = @NamesID)
SET @SQL = N'SELECT * FROM OpenQuery ( ADSI, ''SELECT homeDirectory,Title,legacyExchangeDN,displayName, telephoneNumber, mail, mobile,samAccountName
FROM ''''LDAP://domain.com''''
WHERE objectClass = ''''User'''' and samAccountName = ''''' + @eID+ ''''''') As tblADSI'
INSERT INTO @DBresults
EXEC sp_executesql @SQL
DECLARE DBcursor CURSOR FOR
SELECT * from @DBresults;
Open DBcursor; FETCH DBCursor into @eID, @mobile, @mail, @phone, @Name, @legacyExchangeDN, @Title, @homeDirectory;
CLOSE DBcursor; DEALLOCATE DBcursor;
UPDATE XXX.dbo.tblNames
SET Job_Title = @Title,
Phone = @Phone
Where NamesID = @NamesID;
END
【问题讨论】:
-
您在第一个触发器中使用游标检索单个值并将其存储到变量中?
-
一个触发器,其中包含一个游标,然后该触发器调用另一个触发器,该触发器又调用一个更新ADSI并再次包含另一个游标的存储过程......我的妈呀! 触发器应该非常小、快速、灵活。不要不在触发器中进行任何广泛的处理! 从不如果您需要处理 - 让触发器在“命令”表中插入一行,然后有一个单独的异步进程来完成繁重的工作!还有:在触发器内,N E V E R。 . . E V E R 使用光标!
-
哇,这真是一团糟。您在触发器中有一个光标。游标不查询 INSERTED。它只能处理单行插入。在触发器中使用游标带来的性能问题是惊人的。你到底为什么要使用游标来填充单个值?您的第二个触发器具有相同的基本缺陷,它无法处理基于集合的操作。然后你的存储过程使用了同样有缺陷的概念,即使用游标填充变量。
-
好吧伙计们..与其批评我做错的一切,我该如何正确地做...请注意,直到上周,我从未写过触发器...不知道他们甚至存在。我不宣称对他们一无所知。我理解批评的必要性,但来吧,帮帮我。
标签: sql sql-server stored-procedures