2

特定の条件下で爆撃する動的SQLステートメントがいくつかあるので、デバッグしようとしています。次のように構築されます。

declare @sql varchar(4000);
...
select @sql = '<part1>';
...
select @sql = @sql + '<part2>';
...
select @sql = @sql + '<part3>';
...
begin 
execute(@sql);
select @ec__errno = @@error
    if @ec__errno != 0
    begin
    if @@trancount != 0
    begin
    rollback;
    end
return @ec__errno;
end;
... 

私が言ったように、それはループの特定の反復で爆弾をします(なぜこのように実装されているのかを尋ねないでください、私はバグを修正しているだけです)。 。私は最初の255文字だけを手に入れていると思います。substring(@sql, 0, 200)で結果を見ています'substring(@sql,0,200)' could not be evaluated。助けてください。200から199までの0から199までのサブストリングを見て、このことを一緒に断ち切ってデバッグしたいと思っていました。

あなたからのポインタをいただければ幸いです。ありがとう!

4

2 に答える 2

6

ストアド プロシージャで動的 SQL を使用する必要がある場合は、次のようにします。ビットフィールドである debug の入力変数を追加します。0 の場合は exec ステートメントが処理され、1 の場合は代わりに print ステートメントが取得されます。デバッグに似たようなことをすることをお勧めします。実行する代わりに、SQL の結果を出力するか、ループで発生しているように見えるため、SQl をテーブルに挿入する可能性があります。次に、構築されたSQLを調べて、どこで問題が発生したかを確認できます。

Declare debug bit
set debug = 1

...
if debug = 1 Begin     Print @SQL End
Else 
Begin Exec (@sql) End

あるいは

mydynamiccode_logging という名前のテーブルを作成します (max sql ステートメントと同じ長さの sql 列、rundatecolumn、および必要に応じて他の列を使用します (sql ステートメント、ユーザー、アプリケーションを構成するために使用される入力変数を検討します)。複数の人がこのコードを使用している場合)

exec ステートメントを実行する前に、次のように実行します。

insert mydynamiccode_logging (sql, rundate)
values (@sql, getdate()) 

また、デバッグ ビット フィールドを追加して、デバッグ モードに変更したときにのみログを記録することも、常にログを記録することもできます。これは、システムと、これにかかる余分な時間と、システムの残りの部分がどれだけ非難されているかによって異なります。ロギングによって製品の速度を大幅に低下させたくありません。

于 2010-03-01T22:01:09.983 に答える
1

次のようにすると、失敗のみがログに記録されます。

BEGIN TRY

    DECLARE @LogString   varchar(max)

    --record input parameters
    SET @LogString='@Param1='+COALESCE(''''+@Param1+'''','null')
                   +@Param2='+COALESCE(''''+@Param2+'''','null')
                   +@ParamDate='+COALESCE(''''+CONVERT(varchar(23),@ParamDate,121)+'''','null')
                   +@ParamInt='+COALESCE(''''+CONVERT(varchar(10),@Paramint)+'''','null')

    --build @SQL_String String here
    --repeat as necessary
    SET @LogString=ISNULL(@LogString)+'; '+.... --every logic twist record what is going on

    EXEC (@SQL_String)

END TRY
BEGIN CATCH

    IF XACT_STATE()!=0
    BEGIN
        ROLLBACK TRANSACTION
    END

    SET @LogString=ISNULL(@LogString,'')+'; '
                 +CASE WHEN ERROR_NUMBER()     IS NOT NULL THEN 'Msg '         +CONVERT(varchar(30),   ERROR_NUMBER()     ) ELSE '' END
                 +CASE WHEN ERROR_SEVERITY()   IS NOT NULL THEN ', Level '     +CONVERT(varchar(30),   ERROR_SEVERITY()   ) ELSE '' END
                 +CASE WHEN ERROR_STATE()      IS NOT NULL THEN ', State '     +CONVERT(varchar(30),   ERROR_STATE()      ) ELSE '' END
                 +CASE WHEN ERROR_PROCEDURE()  IS NOT NULL THEN ', Procedure ' +                       ERROR_PROCEDURE()    ELSE '' END
                 +CASE WHEN ERROR_LINE()       IS NOT NULL THEN ', Line '      +CONVERT(varchar(30),   ERROR_LINE()       ) ELSE '' END
                 +CASE WHEN ERROR_MESSAGE()    IS NOT NULL THEN ', '           +                       ERROR_MESSAGE()      ELSE '' END

    INSERT INTO ErrorLog Values (@SQL_String)
    INSERT INTO ErrorLog Values (@LogString)

    --will echo back the complete original error message for the calling application
    DECLARE @ErrorMessage nvarchar(400), @ErrorNumber int, @ErrorSeverity int, @ErrorState int, @ErrorLine int
    SELECT @ErrorMessage = N'Error %d, Line %d, Message: '+ERROR_MESSAGE(),@ErrorNumber = ERROR_NUMBER(),@ErrorSeverity = ERROR_SEVERITY(),@ErrorState = ERROR_STATE(),@ErrorLine = ERROR_LINE()
    RAISERROR (@ErrorMessage, @ErrorSeverity, @ErrorState, @ErrorNumber,@ErrorLine)

    RETURN 9999

END CATCH
于 2010-03-01T22:12:44.210 に答える