4

いくつかのストアド プロシージャを動的に生成するために使用している数千行の長さのスクリプトを作成しました。

ストアド プロシージャ内のコメントでストアド プロシージャを生成したスクリプトを参照したい ストアド プロシージャ内のコメントにスクリプト ファイルの行番号を挿入することで、スクリプト ファイル内の行を参照できるようにしたいファイル。

たとえば、次のコードで @@line_number が必要な行番号を指定した場合、@@line_number は 5 である必要があります。

1| declare @job varchar(max)
2| SET @job = '/* this is generated dynamicly by _______  */'
3| SET @job = @job + 'SELECT *' + CHAR(10)
4| SET @job = @job + 'FROM ' + @Table_Name + CHAR(10)
5| SET @job = @job + '/* ' + @@line_number + ' */'
4

3 に答える 3

6

CATCH ブロックは ERROR_LINE() 関数を介してエラーが発生した行番号を返すことができるため、強制エラーで TRY / CATCH を使用できます。読みやすいようにフォーマットされた完全な構造は次のとおりです。

BEGIN TRY
    ;THROW 50000, 'Line#', 1 -- all 3 values are arbitrary, but required
END TRY
BEGIN CATCH
    SET @LineNumber = ERROR_LINE()
END CATCH

ここで、 @LineNumber 変数に設定されている行番号を入力するために、次のようにその構成を 1 行に減らすことができます。

BEGIN TRY;THROW 50000,'',1;END TRY BEGIN CATCH;SET @Line=ERROR_LINE();END CATCH

これが機能する完全な例を次に示します。

SET ANSI_NULLS ON
SET NOCOUNT ON
GO
-- Line #1 (of current batch, not of the entire script if GOs are used)

DECLARE @CRLF NCHAR(2) = NCHAR(13) + NCHAR(10),
        @SQL1 NVARCHAR(MAX) = '',
        @SQL2 NVARCHAR(MAX) = '', -- Line #5
        @Line INT = -1 -- default to an invalid line #

SET @SQL1 += N'/********************' + @CRLF
SET @SQL1 += N' *' + @CRLF
SET @SQL1 += N' * Test Auto-' + @CRLF -- Line #10
SET @SQL1 += N' * Generated Proc 1' + @CRLF
BEGIN TRY;THROW 50000,'',1;END TRY BEGIN CATCH;SET @Line=ERROR_LINE();END CATCH
SET @SQL1 += N' * Line #:' + CONVERT(NVARCHAR(10), @Line) + @CRLF
SET @SQL1 += N' *' + @CRLF
SET @SQL1 += N' ********************/' + @CRLF -- Line #15

-- more code here

SET @SQL2 += N'/********************' + @CRLF
SET @SQL2 += N' *' + @CRLF -- Line #20
SET @SQL2 += N' * Test Auto-' + @CRLF
SET @SQL2 += N' * Generated Proc 2' + @CRLF
BEGIN TRY;THROW 50000,'',1;END TRY BEGIN CATCH;SET @Line=ERROR_LINE();END CATCH
SET @SQL2 += N' * Line #:' + CONVERT(NVARCHAR(10), @Line) + @CRLF
SET @SQL2 += N' *' + @CRLF -- Line #25
SET @SQL2 += N' ********************/' + @CRLF

PRINT @SQL1
PRINT @SQL2
GO

Proc 1 と Proc 2 で返される行番号はそれぞれ 12 と 23 で、どちらも正しい値です。

THROW コマンドは SQL Server 2012 で開始されたことに注意してください。SQL Server 2005、2008、または 2008 R2 を使用している場合は、THROW の代わりに RAISERROR() 関数を使用する必要があります。

于 2013-11-11T21:52:38.927 に答える
1

SolomonRutzky の回答を少し変更して、2012 年より前の SQL Server バージョンで動作するようにしました。

DECLARE @Line INT
SET @Line = 0 BEGIN TRY RAISERROR ('Line#', 11, 1)WITH NOWAIT   END TRY BEGIN CATCH SET @Line=ERROR_LINE() END CATCH

PRINT('/* testing ... I messed up somewhere near line: ' + CONVERT(varchar(10), ISNULL(@Line, 0)) + ' */')
于 2014-05-06T03:08:48.160 に答える