1

シナリオ: 2 つの列を持つ SQL 2005 テーブル VR_MQLOAD - 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を呼び出すトリガーが実行され、すべてが正常に機能します。

ここに問題があります.... 失敗している外部プログラムがあります。プロファイラーでは、次のコマンドが実行されていることがわかります。

declare @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' select @ 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 アクションがビジネス エラーで完了しました: 0 更新のために結果セットが生成されました」です。

前もって感謝します !

4

2 に答える 2

1

結果を返すトリガーからのアクションは避ける必要があります。

作成トリガーから

トリガーに関する一般的な考慮事項

結果を返す

トリガーから結果を返す機能は、SQL Server の将来のバージョンでは削除される予定です。結果セットを返すトリガーは、それらと連携するように設計されていないアプリケーションで予期しない動作を引き起こす可能性があります。新しい開発作業でトリガーから結果セットを返すことは避け、現在これを行っているアプリケーションを変更することを計画してください。トリガーが結果セットを返さないようにするには、トリガーからの結果を許可しないオプションを 1 に設定します。

于 2013-10-04T16:38:03.527 に答える