1

场景:SQL 2005 表 VR_MQLOAD 有 2 列 - MQKEY (PK, int, not null) 和 MQDATA (varchar(8000),null)

这个表有一个oninsert触发器,这个触发器调用了一个存储过程。

从查询窗口中,我运行:

declare @P0 as nvarchar(4000)
set @P0 = N'TRIG1420441662MF1991782 CAROLYN 201310021356449320131002Y'
insert into dbo.VR_MQLOAD (MQDATA) values(@P0) 

触发器运行,调用 sp,一切正常。

这就是问题所在......我们有一个失败的外部程序。在探查器中,我可以看到正在运行此命令:

声明@p1 int set @p1=17 exec sp_prepexec @p1 output,N'@P0 nvarchar(4000)',N'insert into dbo.VR_MQLOAD (MQDATA) values(@P0)',N'TRIG1420473882MF1993755 CAROLYN 201310031519469020131002Y' 选择@ p1

对我来说,这看起来完全一样。但是,当它执行时,触发器运行,它调用 sp,并且 SP 失败。请参阅下面的 SP....

USE [VEHICLE]
GO
/****** Object:  StoredProcedure [dbo].[VR_UpdateTrigLog]    Script Date: 10/04/2013 11:22:24 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER OFF
GO

ALTER PROCEDURE [dbo].[VR_UpdateTrigLog]
              @sMQData varchar(53),
              @sErrorMsg varchar(255)  OUTPUT
    AS
--
    DECLARE @currentDate datetime
    DECLARE @iCount as integer
--
    DECLARE @sPVI varchar(9)
    DECLARE @sCSN varchar(11)   
    DECLARE @sInputAddress varchar(8)                                
    DECLARE @sTrigDate varchar(8)
    DECLARE @sTrigTime varchar(6)
    DECLARE @sProdDate varchar(8)
    DECLARE @sEventNum varchar(6)
    DECLARE @tmp_TrigDate varchar(9)
    DECLARE @tmp_TrigTime varchar(8)
    DECLARE @tmp_ProdDate varchar(8)
    DECLARE @tmp_CSN varchar(11)
    DECLARE @sUpdateVBI varchar(1)
--
    SELECT @currentDate = GETDATE()
--
    SELECT @sPVI = substring(@sMQData,1,9)
    SELECT @sCSN = substring(@sMQData,10,11)
    SELECT @sInputAddress = substring(@sMQData,21,8)
    SELECT @sTrigDate = substring(@sMQData,29,8)
    SELECT @sTrigTime = substring(@sMQData,37,6)
    SELECT @sEventNum = substring(@sMQData,43,2)
    SELECT @sProdDate = substring(@sMQData,45,8)
    SELECT @sUpdateVBI = substring(@sMQData,53,1)
--
--  Check if rows PVI exists in VBI. 
--  If PVI does not exist, send error message to client, roll back tran
--

    SELECT * 
    FROM vehicle.dbo.vr_VBI
    WHERE pvi=@sPVI

如果我在上面的 select 语句之前放置一个“GoTo Finalize”,则初始插入表将完成并且不会回滚。如果不是,那么它在此选择上失败并回滚所有内容。

那么......这个外部程序通过 sp_prepexec 插入的方式与通过查询窗口手动运行它的方式有什么不同???

关于如何查看与为什么在这里失败相关的错误消息的任何建议?我在 SQL 代码中进行故障排除是绿色的......不确定从外部程序运行此代码时如何查看该代码上的错误。顺便说一句...在外部程序的日志中返回的错误是“db_write action is completed with business ERROR: 0 A result set was generated for update”。

提前致谢 !

4

2 回答 2

1

您应该避免来自返回结果的触发器的操作。

创建触发器

一般触发器注意事项

返回结果

从触发器返回结果的功能将在 SQL Server 的未来版本中删除。返回结果集的触发器可能会在不是为使用它们而设计的应用程序中导致意外行为。避免在新开发工作中从触发器返回结果集,并计划修改当前执行此操作的应用程序。要防止触发器返回结果集,请将禁止来自触发器的结果选项设置为 1。

于 2013-10-04T16:38:03.527 回答
0

仅供参考......事实证明,存储过程将从“SELECT”语句中获得的内容返回给触发器,然后返回给调用应用程序。我们修复它的方法是创建一个参数并将 SELECT 的结果返回到参数中,然后进行相应的处理。通过将结果返回给参数,它阻止了它返回给调用应用程序。

于 2013-10-08T17:06:42.870 回答