我有After Update
此触发器适用于将在链接服务器上更新2个表的服务器
参见代码
ALTER TRIGGER [dbo].[tgAfterUpdate] ON [dbo].[KS_3EToVision]
AFTER UPDATE
AS
BEGIN
BEGIN TRY
BEGIN TRANSACTION -- Start the transaction
DECLARE @MatterNumber varchar(15);
SELECT @MatterNumber = i.MatterNumber FROM inserted i;
IF EXISTS(SELECT * FROM [FSSQLDEV01].[collnab].[dbo].[collection_header] WHERE Ch_file_number COLLATE DATABASE_DEFAULT = @MatterNumber COLLATE DATABASE_DEFAULT)
--UPDATE
IF (SELECT Ch_matter_status FROM [FSSQLDEV01].[collnab].[dbo].[collection_header] WHERE Ch_file_number COLLATE DATABASE_DEFAULT = @MatterNumber COLLATE DATABASE_DEFAULT ) = 'Current'
BEGIN
--Parent table
UPDATE [FSSQLDEV01].[collnab].[dbo].[collection_header]
SET
Ch_start_date = i.OpenDate
FROM
Inserted i
WHERE ch_file_number COLLATE DATABASE_DEFAULT = @MatterNumber COLLATE DATABASE_DEFAULT
----Child table
UPDATE [FSSQLDEV01].[collnab].[dbo].[collections]
SET
Defendant_1 = i.Description
, Loan_Number_1 = i.Comments
, Client = i.KS_BookName
, Date_Instructed = i.OpenDate
, Person_Responsible_name = i.ResponsibleFeeEarnerName
, Person_Responsible_Email = i.ResponsibleFeeEarnerEmail
, Person_Acting_name = i.BillingFeeEarnerName
, Person_Acting_email = i.BillingFeeEarnerEmail
, Agent_Acting_name = i.BillingFeeEarnerName
, Agent_Acting_email = i.BillingFeeEarnerEmail
, CBA_Panel_Service_Area = i.KS_ServiceCat
, HBN_Number = i.KS_ClientAcctRef
, St_George_Contact = i.KS_Instructor
FROM
Inserted i
WHERE Left(Collections.file_number,6) COLLATE DATABASE_DEFAULT = @MatterNumber COLLATE DATABASE_DEFAULT
END
--If we reach here, success!
COMMIT
END TRY
BEGIN CATCH
-- Whoops, there was an error
IF @@TRANCOUNT > 0
ROLLBACK
-- Raise an error with the details of the exception
DECLARE @ErrMsg nvarchar(4000), @ErrSeverity int
SELECT @ErrMsg = ERROR_MESSAGE(),
@ErrSeverity = ERROR_SEVERITY()
RAISERROR(@ErrMsg, @ErrSeverity, 1)
END CATCH
END
如果我尝试使用触发器之外的相同条件的更新语句,它只需要1秒钟,但在触发器内部最多可能需要45秒。
我已将其缩小到第二个更新语句是问题,因为如果我删除第二个更新语句,它将快速执行。
我还附上了一个图片
我还有一个Trigger for Insert,它可以在一秒内快速完成,而且一个用于删除,这将在触发器中延长一段时间但如果我删除触发器之外的2个删除语句,则运行正常。
USE [TE_3E_TRG]
GO
/****** Object: Trigger [dbo].[tgAfterDelete] Script Date: 08/30/2012 11:24:33 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER TRIGGER [dbo].[tgAfterDelete] ON [dbo].[KS_3EToVision]
AFTER DELETE
AS
begin
BEGIN TRY
BEGIN TRANSACTION -- Start the transaction
Begin
--Parent table
DELETE FROM [FSSQLDEV01].[collnab].[dbo].[collection_header] WHERE ch_file_number COLLATE DATABASE_DEFAULT = (SELECT d.MatterNumber FROM deleted d) COLLATE DATABASE_DEFAULT
--Child table
DELETE FROM [FSSQLDEV01].[collnab].[dbo].[collections] WHERE Left(file_number,6) COLLATE DATABASE_DEFAULT = (SELECT d.MatterNumber FROM deleted d) COLLATE DATABASE_DEFAULT
END
-- If we reach here, success!
COMMIT
END TRY
BEGIN CATCH
-- Whoops, there was an error
IF @@TRANCOUNT > 0
ROLLBACK
-- Raise an error with the details of the exception
DECLARE @ErrMsg nvarchar(4000), @ErrSeverity int
SELECT @ErrMsg = ERROR_MESSAGE(),
@ErrSeverity = ERROR_SEVERITY()
RAISERROR(@ErrMsg, @ErrSeverity, 1)
END CATCH
有谁知道为什么在执行触发器内的语句和触发器的外侧之间可能会出现执行时间的巨大差异?
答案 0 :(得分:0)
您正在使用本地虚拟插入表加入远程表。这可能涉及将整个表从远程服务器复制到本地并在本地过滤。
这是非常罕见的情况,使用游标和逐行更新可能会提高性能。
BTW marc_s的观点是正确的,你的代码应该考虑插入表有多于一行的可能性。