Sql server T-SQL触发器导致阻塞
救命啊!执行以下触发器后会导致阻塞:Sql server T-SQL触发器导致阻塞,sql-server,sql-server-2008,tsql,locking,blocking,Sql Server,Sql Server 2008,Tsql,Locking,Blocking,救命啊!执行以下触发器后会导致阻塞: USE [Automation] GO /****** Object: Trigger [dbo].[AfterInsertSendEmail] Script Date: 08/06/2012 22:05:54 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO -- ============================================= -- Author:
USE [Automation]
GO
/****** Object: Trigger [dbo].[AfterInsertSendEmail] Script Date: 08/06/2012 22:05:54 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Chris Cannon
-- Create date: 20120806
-- Description: TBC
-- =============================================
ALTER TRIGGER [dbo].[AfterInsertSendEmail]
ON [dbo].[Enquiry]
AFTER INSERT
AS
BEGIN;
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for trigger here
DECLARE @l_profile_name nvarchar(128) = 'Automation Enquiries';
DECLARE @l_importance varchar(6) = 'High';
DECLARE @l_sensitivity varchar(12) = 'Personal';
DECLARE @l_recipients varchar(500) = 'a.n.other@somewhere.co.uk';
DECLARE @l_copy_recipients varchar(500) = 'b.n.other@somewhere.co.uk';
DECLARE @l_blind_copy_recipients varchar(500) = 'c.n.other@somewhere.co.uk';
DECLARE @l_reply_to varchar(500) = (SELECT [EmailAddress] FROM [inserted]);
DECLARE @l_subject nvarchar(255) = (SELECT 'New Enquiry From ' + [FirstName] + ' ' + [LastName] FROM [inserted]);
DECLARE @l_body nvarchar(500) = 'TBC';
DECLARE @l_query nvarchar(500) = 'SELECT TOP(1) * FROM [Automation].[dbo].[Enquiry] ORDER BY [Id] DESC';
DECLARE @l_query_result_separator char(1) = CHAR(9);
DECLARE @l_query_result_no_padding bit = 1;
DECLARE @l_attach_query_result_as_file bit = 1;
DECLARE @l_query_attachment_filename nvarchar(260) = (SELECT 'automation_enquiry_' + REPLACE(REPLACE(REPLACE(CONVERT(nvarchar(19), [DateSubmitted], 120), '-', ''), ' ', ''), ':', '') + '.csv' FROM [inserted]);
DECLARE @l_append_query_error bit = 1;
EXEC [msdb].[dbo].[sp_send_dbmail]
@profile_name = @l_profile_name
, @importance = @l_importance
, @sensitivity = @l_sensitivity
, @recipients = @l_recipients
, @copy_recipients = @l_copy_recipients
, @blind_copy_recipients = @l_blind_copy_recipients
, @reply_to = @l_reply_to
, @subject = @l_subject
, @body = @l_body
, @query = @l_query
, @query_result_separator = @l_query_result_separator
, @query_result_no_padding = @l_query_result_no_padding
, @attach_query_result_as_file = @l_attach_query_result_as_file
, @query_attachment_filename = @l_query_attachment_filename
, @append_query_error = @l_append_query_error;
END;
据我所知,它看起来像这样:
DECLARE @l_query nvarchar(500) = 'SELECT TOP(1) * FROM [Automation].[dbo].[Enquiry] ORDER BY [Id] DESC';
可能是阻塞了某些东西,或者触发器本身阻塞了该语句
我试过几件运气不好的事
请帮忙 尝试使用NOLOCK
SELECT TOP(1) * FROM [Automation].[dbo].[Enquiry] WITH (NOLOCK) ORDER BY [Id] DESC
<>你在一个事务的中间,至少那一行是锁定的,然后你发送一个邮件,邮件在同一个表上运行一个选择顶部,你有一个锁定……/p> 您可以按照losbear的建议尝试nolock,但是,既然您运行的查询可能是为了显示您刚刚插入的记录的详细信息,并且您已经在触发器中插入了Available,那么为什么还要使用@query呢
我个人从来就不喜欢在我的交易中发送邮件的想法。我宁愿将请求排队,提交事务,然后让一些服务进行邮件处理。不过,这需要做更多的工作。插入和删除的是表,因此它们可以表示集合操作的结果。假设触发器总是只包含一行,设计触发器通常是一个糟糕的计划。@HABO但如果我知道一次只插入一行,那么我就不必担心了?声明@l_查询的语句只分配了一个字符串文本。它挡不住。如果我有一辆四轮马车给每一个确信不会有超过一排人受到影响的人,我现在就可以坐在沙丘车上绕火星转了。如果它不咬你,那仍然是一场维护灾难。由于插入的行不能超过一行,请添加一个断言:如果选择count42 from inserted>1,则出现错误“[AfterInsertSendEmail]Chris承诺不会这样做”,13,0。我爱太阳神boo-boo。查询的唯一查询是通过@l_query传递的。您可以为@l_query创建值,以便它返回您从中提取的文本值插入:选择42作为inquiryId,选择UncleBob作为UserName。。。。不需要,没有机会阻止。感谢您的明确回复。重新。排队-我的理解是sp_send_dbmail会对电子邮件进行排队。为什么要麻烦@query是什么意思?它需要为电子邮件生成附件。错调,我的意思是建立一个文本查询,例如选择“Fred”作为名称等。sendmail对电子邮件进行排队,它不会对生成电子邮件进行排队。因此,您有一个电子邮件队列表,触发对它的插入,然后是另一个使用sendmail对来自它的电子邮件进行队列处理的进程。当xp_sendmail可用时,它非常有用,因为您的邮件服务器的问题导致数据库事务失败。文字字符串是个好主意,但它太多了,此外,这是我很少使用SELECT*而不用担心的一次,我不想错过它。