请问:为什么触发器触发后不能退出,还死机,触发器有什么限制的?
我写的触发器材如下:单单执行触发器中的SQL语句是没问题的
ALTER TRIGGER [TR_BlogArticleCreateXMLFile] 
   ON  [dbo].[T_SNETBlogArticle]
   AFTER INSERT
AS 
BEGIN
DECLARE @Str NVARCHAR(2000)
    DECLARE @Par NVARCHAR(100)
DECLARE @Span NVARCHAR(50)
--DECLARE @Const NVARCHAR(500)
CREATE TABLE tb(PartName NVARCHAR(100))
INSERT tb SELECT  ' <channel>'
UNION ALL SELECT ' <title>Liftoff News</title>'
UNION ALL SELECT ' <link>http://liftoff.msfc.nasa.gov</link>'
UNION ALL SELECT ' <description>Liftoff to Space Exploration.</description>'
UNION ALL SELECT ' <title>Liftoff News</title>'
UNION ALL SELECT ' <pubDate>Tue, 10 Jun 2003 04:00:00 GMT</pubDate>'
UNION ALL SELECT ' <lastBuildDate>Tue, 10 Jun 2003 09:41:01 GMT</lastBuildDate>'
UNION ALL SELECT ' <docs>http://blogs.law.harvard.edu/tech/rss</docs>'
UNION ALL SELECT ' <generator>Weblog Editor 2.0</generator>'
UNION ALL SELECT ' <managingEditor>[email protected]</managingEditor>'
UNION ALL SELECT ' <webMaster>[email protected]</webMaster>'
--==============================================================================================
    --select top 10 * INTO #tb from T_SNETBlogArticle ORDER BY SNETBlogArticleCreateDate DESC
--==============================================================================================
SET @Span = '+char(13)+char(10)+'
SET @Par = '" queryout "G:\NWeb\a.xml" /S"B992586A0529472\SNET2008T" /U"sa" /P"123456" /c'
    set @Str= 'bcp "select' + '''<?xml version="1.0"?>'''
+'union all select' + '''<rss version="2.0">''' 
+ 'union all (select PartName FROM test.dbo.tb)'
+'union all (select top 10' + '''  <item>''' + @Span
+''' <title>''' + '+SNETBlogArticleTitle+' + '''</title>'''+ @Span
+''' <link>''' + '+SNETBlogArticleTitle+' + '''</link>''' + @Span
+''' <description>''' + '+SNETBlogArticleTitle+' + '''</description>''' + @Span
+''' <pubDate>''' + '+CONVERT(NVARCHAR(15),SNETBlogArticleCreateDate,23)+' + '''<pubDate>''' + @Span
+''' <guid>''' + '+SNETBlogArticleTitle+' + '''</guid>''' + @Span
+'''  </item>''' 
+'from (select top 10 * from test.dbo.T_SNETBlogArticle ORDER BY SNETBlogArticleCreateDate DESC) AS T_Article  ) union all select' 
+''' </channel>'''  
+'union all select' + '''</rss>''' 
+ @Par    
exec  master..xp_cmdshell @Str
DROP TABLE tb
--DROP TABLE #tbEND

解决方案 »

  1.   

    明白了,还是xp_cmdshell的问题:触发器和引发触发的动作INSERT是一个事务,在这个事务结束之前,bcp是无法访问表[T_SNETBlogArticle]的。bcp等待触发器,触发器等待bcp,导致死锁。
      

  2.   

    触发器在事务中你在里面建表, 意味着是在事务没有提交的情况下完成的
    CREATE TABLE tb(PartName NVARCHAR(100)) 在事务没有提交的情况下, 调用 xp_cmdshell 执行 bcp , 这里面的进程与触发器不是同一个, 既然不是同一个, bcp的操作肯定被触发器阻塞, 所以必须等, 而触发器不结束, 事务不提交, 所以这个等永远没有尽头
    所以不死才怪
      

  3.   

    你可以在触发器开始的时候, 将所有的事务提交掉(COMMIT TRAN, 直接到 @@TRANCOUNT = 0)这样你后面的表就不在事务中, bcp 也就正常了这样做的缺点是影响了外层调用者的事务, 可能导致不良后果
      

  4.   

    另外一种做法是建立一个永乐性的 永久性的表bcp 读取这个表的时候, 使用 from test.dbo.T_SNETBlogArticle WITH(NOLOCK)
    这样可以不加锁的读取到数据
      

  5.   

    嗯,有道理,建不建tb表都一样死锁,因为bcp引用了触发器的宿主表:select top 10 * from test.dbo.T_SNETBlogArticle
      

  6.   

    听你们这么说,一共有两个地方引发了死锁:
    1是:CREATE TABLE tb(PartName NVARCHAR(100))
    2是:select top 10 * from test.dbo.T_SNETBlogArticle
    我说的对吗?
    受益良多