Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何调试T-SQL触发器?_Sql - Fatal编程技术网

如何调试T-SQL触发器?

如何调试T-SQL触发器?,sql,Sql,我有一个表t,它有一个名为trgInsAfter的“after insert”触发器。我该如何调试它呢?我不是这方面的专家,所以提出的问题和执行的步骤可能看起来很愚蠢 到目前为止,我执行的步骤包括: 1.通过SSMS(使用Windows管理员帐户)连接到服务器实例 右键单击SSMS中左侧树中的触发器节点并双击将其打开,触发器的代码将在新的查询窗口(称为该窗口-1)中打开,如下所示:blah ALTER TRIGGER trgInsAfter AS .... BEGIN ... END 打开另

我有一个表t,它有一个名为trgInsAfter的“after insert”触发器。我该如何调试它呢?我不是这方面的专家,所以提出的问题和执行的步骤可能看起来很愚蠢

到目前为止,我执行的步骤包括: 1.通过
SSMS
(使用Windows管理员帐户)连接到
服务器实例

  • 右键单击SSMS中左侧树中的触发器节点并双击将其打开,触发器的代码将在新的查询窗口(称为该窗口-1)中打开,如下所示:blah

    ALTER TRIGGER trgInsAfter AS .... BEGIN ... END
    
  • 打开另一个查询窗口(称此窗口为-2),输入sql以在表t中插入一行:

    insert t(c1,c2) values(1,'aaa')
    
  • 在Window-1(触发器代码)中设置断点

  • 在Window-2中设置断点(插入SQL代码)

  • 当Window-2为当前窗口时,单击工具栏上的“调试”按钮

    插入SQL代码的断点被命中,但当我查看Window-1时,触发器代码中的断点有一个工具提示:“无法绑定SQL断点,包含断点的对象未加载”
  • 我可以理解这个问题:
    SSMS
    如何知道Window-1中的代码是触发器

    我想调试?我看不出哪里可以告诉SSMS‘嘿,这个查询编辑器中的代码是表t的inssert触发器的代码’

    有什么建议吗


    谢谢

    SSMS中有一个调试菜单,但您可能需要在服务器上才能进行调试,因此如果是远程访问,可能不会为其设置。 该调试选项将允许您执行代码,并进入触发器并以这种方式进行调试(就像调试大多数其他代码一样)

    如果无法访问调试菜单/功能,则必须“手动”调试:

    首先,通过将触发器的输入插入调试表,确保触发器正确运行。然后您可以验证是否正确调用了它。
    然后,您可以像调试任何其他sql查询一样,使用调试表中的值调试触发器的查询。

    您实际上已经考虑过了

    我首先在一个窗口中运行此查询(以进行设置):

    然后我可以扔掉那扇窗户。我打开一个新的查询窗口,写下:

    insert into X(ID) values (1),(2)
    

    并在该行上设置断点。然后,我启动调试器(
    Debug
    从菜单或工具栏或Alt-F5)并等待(有一段时间,调试器从来都不会太快)使其达到该断点。然后,点击这里,我选择进入(F11)。lo(再等待一小段时间后)会打开一个新窗口,这是我的触发器,调试器停止的下一行代码是触发器中的
    插入Y…
    行。我现在可以在触发器中设置任何进一步的断点。

    无论出于何种原因,我都无法让@Damien\u异教徒的解决方案起作用。 至少,不是在连接到表的触发器上。当我执行
    步进
    时,它每次只执行查询,而不执行触发器

    然后我注意到,在该方法的注释中,您无论如何都看不到任何表值

    所以

    我最终创建了一个通用调试表

    USE [Your_DB]
    GO
    
    SET ANSI_NULLS ON
    GO
    
    SET QUOTED_IDENTIFIER ON
    GO
    
    SET ANSI_PADDING ON
    GO
    
    CREATE TABLE [dbo].[Debug_Table](
        [ID] [int] IDENTITY(1,1) NOT NULL,
        [Name] [varchar](60) NOT NULL,
        [Value] [sql_variant] NULL,
        [Description] [varchar](max) NULL,
        [Captured] [datetime] NOT NULL
    ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
    
    GO
    
    SET ANSI_PADDING OFF
    GO
    
    然后在我的扳机里我做了这样的事情

    DECLARE @ItemNum nvarchar(128)
    SELECT  @ItemNum = Item_Number FROM inserted
    
    DECLARE @debugOn as bit = 1
    -- Debug
        IF @debugOn = 1
        BEGIN
            INSERT INTO Debug_Table (Name, Value, Description, Captured)
            VALUES ( 'Item Number', @ItemNum, 'The item number from the inserted table in tr_VaultItemIterations_ZCode_Monitor.', GETDATE())
        END;
    -- End Debug
    
    从表中触发触发器后,我可以查看插入到Debug_表中的任何变量


    调试完成后,您可以通过将
    @debugOn
    变量更改为
    0
    轻松关闭调试插入,以防将来需要再次调试;或者干脆完全删除调试代码。

    我也无法进入,它将直接进入我的
    而不是插入
    触发器。因此,我最终用以下内容替换触发器:

    ALTER TRIGGER [MyView_Instead_Insert] 
       ON  [MyView] 
       INSTEAD OF INSERT
    AS 
    BEGIN
    SET NOCOUNT ON
    
    select * into temp from INSERTED
    
    END
    

    它创建了一个名为temp的表,其中包含插入的
    列名和值

    太好了,F11成功了!我想我使用C++/C#代码的时间太长了,习惯于加载所有相关的源代码文件和预设断点:(只想在包含触发器源代码的自动弹出窗口中添加,其路径的格式如下:
    mssql:://mywin7pc\bdsql/mydemodhb/?/=338100245
    \//?/=idSadly,我无法看到虚拟表中的值
    inserted
    deleted
    @Santhos-不仅仅是
    inserted
    >和
    删除了
    。你会发现在调试时检查任何表内容都不是一个简单的方法。恐怕调试经验非常缺乏。@Damien_不相信你是完全正确的。我已经决定采取另一种方法,创建一个临时调试表,我正在使用Inserts、时间戳和一些辅助触发器。
    
    ALTER TRIGGER [MyView_Instead_Insert] 
       ON  [MyView] 
       INSTEAD OF INSERT
    AS 
    BEGIN
    SET NOCOUNT ON
    
    select * into temp from INSERTED
    
    END