문제

저장된 절차를 동적으로 생성하는 데 사용하는 수천 줄의 스크립트를 작성했습니다.

저장 프로 시저에서 주석에 저장된 절차를 생성 한 스크립트를 참조하고, 스크립트 파일의 줄 번호를 저장 프로 시저의 주석에 삽입하여 스크립트 파일의 줄을 참조 할 수 있기를 원합니다. 파일.

예를 들어 @@ 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 + ' */'
도움이 되었습니까?

해결책

캐치 블록이 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 변수가 설정중인 줄 번호로 채워 지도록하려면 다음과 같이 해당 구조물을 한 줄로 줄일 수 있습니다.

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 () 함수를 사용해야합니다.

다른 팁

나는 바뀌었다 솔로몬 루츠키의 대답 다트는 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)) + ' */')

현재 줄 번호를 반환 할 내장 기능을 찾지 못했기 때문에 나에게 줄 번호를 찾기 위해 함수를 만들기 시작했습니다.

현재 실행중인 쿼리의 텍스트를 상단에 가져 와서 변수를 선언 한 다음 함수 호출 및 @LineCounter 증가 코드를 복사하고 지나면 현재 줄 번호를 얻을 수 있습니다.

    DECLARE @var1 NVARCHAR(MAX) 
    SELECT @var1 = sqltext.TEXT
    FROM sys.dm_exec_requests req
    CROSS APPLY sys.dm_exec_sql_text(sql_handle) AS sqltext
    WHERE req.session_id = @@SPID
    DECLARE @LineCounter int
    SET @LineCounter = 0
    DECLARE @Current_Line_Number int
    SET @Current_Line_Number = 0
SET @LineCounter = @LineCounter + 1
SELECT @Current_Line_Number = [MSMS].[dbo].[ReturnLineNumber] (@var1, @LineCounter)
PRINT @Current_Line_Number

이것이 기능입니다

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:      James J
-- Create date: 11/11/2013
-- Description: Function to return the line number for 
-- where the query was called from when passed the query 
-- an the count of the times it has already been used.
-- =============================================
ALTER FUNCTION ReturnLineNumber 
(
    @CurrentQuery nvarchar(max), 
    @Count  int
)
RETURNS int
AS
BEGIN
    DECLARE @var1 NVARCHAR(MAX) 
    DECLARE @functionName nvarchar(30)
    SET @functionName = 'ReturnLineNumber'
    SET @var1 = @CurrentQuery

    DECLARE @LineCount int
    SET @LineCount = 0

    IF (CHARINDEX(CHAR(13), @var1) > 0)
    BEGIN
        DECLARE @queryString nvarchar(max)
        SET @queryString = @var1
        DECLARE @LineIndex int
        SET @LineIndex = 1
        DECLARE @LineLength int
        DECLARE @linestring nvarchar(max)
        DECLARE @functioncount int
        SET @functioncount = 0
        WHILE (@LineIndex > 0)
        BEGIN
            SET @LineIndex = CHARINDEX(CHAR(13), @queryString)
            SET @LineLength = LEN(@queryString) - CHARINDEX(CHAR(13), @queryString)
            SET @linestring = SUBSTRING(@queryString, 0, @LineIndex + 1)
            SET @queryString = SUBSTRING(@queryString, @LineIndex + 1, @LineLength)
            SET @LineCount = @LineCount + 1
            IF (CHARINDEX(@functionName, @linestring) > 0)
            BEGIN
                SET @functioncount = @functioncount + 1
                IF (@functioncount = @Count)
                BEGIN
                    RETURN @LineCount
                END
            END
        END
    END
    RETURN 0
END
GO

이것은 줄 번호를 얻는 좋은 방법이 아니며 아마도 기능 호출을 댓글을 달지 못하도록 더 많은 수표를 추가해야하지만 이것이 내가 가장 가까운 순간에 가장 가까운 것입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top