복붙노트

[SQL] 어떻게 인쇄 문을 사용하여 VARCHAR (MAX)를 인쇄하려면?

SQL

어떻게 인쇄 문을 사용하여 VARCHAR (MAX)를 인쇄하려면?

내가하는 코드가 있습니다 :

DECLARE @Script VARCHAR(MAX)

SELECT @Script = definition FROM manged.sys.all_sql_modules sq
where sq.object_id = (SELECT object_id from managed.sys.objects 
Where type = 'P' and Name = 'usp_gen_data')

Declare @Pos int

SELECT  @pos=CHARINDEX(CHAR(13)+CHAR(10),@script,7500)

PRINT SUBSTRING(@Script,1,@Pos)

PRINT SUBSTRING(@script,@pos,8000)

스크립트의 길이는 10,000 문자 주위에 내가 인쇄 정책을 사용하고 있기 때문에 나는 두 개의 인쇄 문을 사용하고 그래서 8000의 최대 보유 할 수있다.

내가 3 인쇄 문을 사용하는 데 사용 18000 개 문자 다음 말입니다 스크립트가있을 때 문제입니다.

그래서 스크립트의 길이에 따라 인쇄 문장의 수를 설정할 수있는 방법이 있나요?

해결법

  1. ==============================

    1.당신은 8000로 나눈 스크립트 길이의 수를 기반으로 WHILE 루프를 할 수 있습니다.

    당신은 8000로 나눈 스크립트 길이의 수를 기반으로 WHILE 루프를 할 수 있습니다.

    EG :

    DECLARE @Counter INT
    SET @Counter = 0
    DECLARE @TotalPrints INT
    SET @TotalPrints = (LEN(@script) / 8000) + 1
    WHILE @Counter < @TotalPrints 
    BEGIN
        -- Do your printing...
        SET @Counter = @Counter + 1
    END
    
  2. ==============================

    2.나는이 오래된 질문 알아요,하지만 내가 한 것은 여기에 언급되지 않습니다.

    나는이 오래된 질문 알아요,하지만 내가 한 것은 여기에 언급되지 않습니다.

    나를 위해 다음과 같은 일했다.

    DECLARE @info NVARCHAR(MAX)
    
    --SET @info to something big
    
    PRINT CAST(@info AS NTEXT)
    
  3. ==============================

    3.다음 해결 방법은 PRINT 문을 사용하지 않습니다. 그것은 SQL Server 관리 Studio와 함께 잘 작동합니다.

    다음 해결 방법은 PRINT 문을 사용하지 않습니다. 그것은 SQL Server 관리 Studio와 함께 잘 작동합니다.

    SELECT CAST('<root><![CDATA[' + @MyLongString + ']]></root>' AS XML)
    

    당신은 내장 된 XML 뷰어를 확장하기 위해 반환 된 XML 클릭 할 수 있습니다.

    표시된 크기에 꽤 관대 한 클라이언트 측의 제한이 있습니다. 필요한 경우 도구로 이동 / 옵션 / 쿼리 결과 / SQL 서버 / 그리드 / XML 데이터에 대한 결과를 조정합니다.

  4. ==============================

    4.다음은이 작업을 수행해야하는 방법이다 :

    다음은이 작업을 수행해야하는 방법이다 :

    DECLARE @String NVARCHAR(MAX);
    DECLARE @CurrentEnd BIGINT; /* track the length of the next substring */
    DECLARE @offset tinyint; /*tracks the amount of offset needed */
    set @string = replace(  replace(@string, char(13) + char(10), char(10))   , char(13), char(10))
    
    WHILE LEN(@String) > 1
    BEGIN
        IF CHARINDEX(CHAR(10), @String) between 1 AND 4000
        BEGIN
               SET @CurrentEnd =  CHARINDEX(char(10), @String) -1
               set @offset = 2
        END
        ELSE
        BEGIN
               SET @CurrentEnd = 4000
                set @offset = 1
        END   
        PRINT SUBSTRING(@String, 1, @CurrentEnd) 
        set @string = SUBSTRING(@String, @CurrentEnd+@offset, LEN(@String))   
    END /*End While loop*/
    

    http://ask.sqlservercentral.com/questions/3102/any-way-around-the-print-limit-of-nvarcharmax-in-s.html에서 촬영

  5. ==============================

    5.이 질문에 더 간단 원하는 뭔가를 건너 왔어요 ... 다음을 시도해보십시오

    이 질문에 더 간단 원하는 뭔가를 건너 왔어요 ... 다음을 시도해보십시오

    SELECT [processing-instruction(x)]=@Script FOR XML PATH(''),TYPE
    
  6. ==============================

    6.이 PROC 제대로 고려 포장 매개 변수 VARCHAR (MAX)에서 인쇄 :

    이 PROC 제대로 고려 포장 매개 변수 VARCHAR (MAX)에서 인쇄 :

    CREATE PROCEDURE [dbo].[Print]
        @sql varchar(max)
    AS
    BEGIN
        declare
            @n int,
            @i int = 0,
            @s int = 0, -- substring start posotion
            @l int;     -- substring length
    
        set @n = ceiling(len(@sql) / 8000.0);
    
        while @i < @n
        begin
            set @l = 8000 - charindex(char(13), reverse(substring(@sql, @s, 8000)));
            print substring(@sql, @s, @l);
            set @i = @i + 1;
            set @s = @s + @l + 2; -- accumulation + CR/LF
        end
    
        return 0
    END
    
  7. ==============================

    7.난 당신의 대부분이를 닮아 이유로 인쇄를 사용하는 imagin 일부 동적 SQL을 디버깅하는 인쇄 문을 사용하여 찾고 있었다.

    난 당신의 대부분이를 닮아 이유로 인쇄를 사용하는 imagin 일부 동적 SQL을 디버깅하는 인쇄 문을 사용하여 찾고 있었다.

    나는 나열 켈시의 솔루션은 N.B. (@Sql 내 @script입니다) 약간의 tweeks으로 작동하는지 볼 수있는 솔루션의 몇 가지 시도 길이는 유효한 기능되지 않습니다 :

    --http://stackoverflow.com/questions/7850477/how-to-print-varcharmax-using-print-statement
    --Kelsey
    DECLARE @Counter INT
    SET @Counter = 0
    DECLARE @TotalPrints INT
    SET @TotalPrints = (LEN(@sql) / 4000) + 1
    WHILE @Counter < @TotalPrints 
    BEGIN
        PRINT SUBSTRING(@sql, @Counter * 4000, 4000)
        SET @Counter = @Counter + 1
    END
    PRINT LEN(@sql)
    

    이 코드는 주석 추가로 출력에 새로운 라인을 수행하지만, 디버깅이 나에게 문제가되지 않습니다.

    벤 B의 솔루션은 완벽하고 내가 켈시의 내 약간의 수정을 사용하도록 선택할 수 있도록 디버깅 코드 라인이 많이 있지만, 가장 elegent입니다. 그것은 재사용 한 줄에서 호출 할 수있는 벤 B의 코드에 대한 MSDB에서 저장 프로 시저와 같은 시스템을 구축 가치가 될 수 있을까요?

    즉 더 쉬웠을 것 때문에 Alfoks '코드는 불행히도 작동하지 않습니다.

  8. ==============================

    8.

    create procedure dbo.PrintMax @text nvarchar(max)
    as
    begin
        declare @i int, @newline nchar(2), @print varchar(max); 
        set @newline = nchar(13) + nchar(10);
        select @i = charindex(@newline, @text);
        while (@i > 0)
        begin
            select @print = substring(@text,0,@i);
            while (len(@print) > 8000)
            begin
                print substring(@print,0,8000);
                select @print = substring(@print,8000,len(@print));
            end
            print @print;
            select @text = substring(@text,@i+2,len(@text));
            select @i = charindex(@newline, @text);
        end
        print @text;
    end
    
  9. ==============================

    9.당신은이를 사용할 수 있습니다

    당신은이를 사용할 수 있습니다

    declare @i int = 1
    while Exists(Select(Substring(@Script,@i,4000))) and (@i < LEN(@Script))
    begin
         print Substring(@Script,@i,4000)
         set @i = @i+4000
    end
    
  10. ==============================

    10.베넷 딜에 의해 작성 PrintMax라는 좋은 기능이있다.

    베넷 딜에 의해 작성 PrintMax라는 좋은 기능이있다.

    사용 온도가 "스키마 오염"을 방지하기 위해 저장 프로 시저 것을 여기에 약간의 수정 버전 (https://github.com/Toolien/sp_GenMerge/blob/master/sp_GenMerge.sql에서 아이디어)

    EXEC (N'IF EXISTS (SELECT * FROM tempdb.sys.objects 
                       WHERE object_id = OBJECT_ID(N''tempdb..#PrintMax'') 
                       AND type in (N''P'', N''PC''))
        DROP PROCEDURE #PrintMax;');
    EXEC (N'CREATE PROCEDURE #PrintMax(@iInput NVARCHAR(MAX))
    AS
    BEGIN
        IF @iInput IS NULL
        RETURN;
    
        DECLARE @ReversedData NVARCHAR(MAX)
              , @LineBreakIndex INT
              , @SearchLength INT;
    
        SET @SearchLength = 4000;
    
        WHILE LEN(@iInput) > @SearchLength
        BEGIN
        SET @ReversedData = LEFT(@iInput COLLATE DATABASE_DEFAULT, @SearchLength);
        SET @ReversedData = REVERSE(@ReversedData COLLATE DATABASE_DEFAULT);
        SET @LineBreakIndex = CHARINDEX(CHAR(10) + CHAR(13),
                              @ReversedData COLLATE DATABASE_DEFAULT);
        PRINT LEFT(@iInput, @SearchLength - @LineBreakIndex + 1);
        SET @iInput = RIGHT(@iInput, LEN(@iInput) - @SearchLength 
                            + @LineBreakIndex - 1);
        END;
    
        IF LEN(@iInput) > 0
        PRINT @iInput;
    END;');
    

    DB 휘티 d 혀라도

    편집하다:

    CREATE 또는 ALTER 우리는 두 EXEC 호출을 피할 수 사용 :

    EXEC (N'CREATE OR ALTER PROCEDURE #PrintMax(@iInput NVARCHAR(MAX))
    AS
    BEGIN
        IF @iInput IS NULL
        RETURN;
    
        DECLARE @ReversedData NVARCHAR(MAX)
              , @LineBreakIndex INT
              , @SearchLength INT;
    
        SET @SearchLength = 4000;
    
        WHILE LEN(@iInput) > @SearchLength
        BEGIN
        SET @ReversedData = LEFT(@iInput COLLATE DATABASE_DEFAULT, @SearchLength);
        SET @ReversedData = REVERSE(@ReversedData COLLATE DATABASE_DEFAULT);
        SET @LineBreakIndex = CHARINDEX(CHAR(10) + CHAR(13), @ReversedData COLLATE DATABASE_DEFAULT);
        PRINT LEFT(@iInput, @SearchLength - @LineBreakIndex + 1);
        SET @iInput = RIGHT(@iInput, LEN(@iInput) - @SearchLength + @LineBreakIndex - 1);
        END;
    
        IF LEN(@iInput) > 0
        PRINT @iInput;
    END;');
    

    DB <> 바이올린 데모

  11. ==============================

    11.라인 피드 및 공백은 좋은 휴식 지점으로 사용합니다 :

    라인 피드 및 공백은 좋은 휴식 지점으로 사용합니다 :

    declare @sqlAll as nvarchar(max)
    set @sqlAll = '-- Insert all your sql here'
    
    print '@sqlAll - truncated over 4000'
    print @sqlAll
    print '   '
    print '   '
    print '   '
    
    print '@sqlAll - split into chunks'
    declare @i int = 1, @nextspace int = 0, @newline nchar(2)
    set @newline = nchar(13) + nchar(10)
    
    
    while Exists(Select(Substring(@sqlAll,@i,3000))) and (@i < LEN(@sqlAll))
    begin
        while Substring(@sqlAll,@i+3000+@nextspace,1) <> ' ' and Substring(@sqlAll,@i+3000+@nextspace,1) <> @newline
        BEGIN
            set @nextspace = @nextspace + 1
        end
        print Substring(@sqlAll,@i,3000+@nextspace)
        set @i = @i+3000+@nextspace
        set @nextspace = 0
    end
    print '   '
    print '   '
    print '   '
    
  12. ==============================

    12.또는 단순히 :

    또는 단순히 :

    PRINT SUBSTRING(@SQL_InsertQuery, 1, 8000)
    PRINT SUBSTRING(@SQL_InsertQuery, 8001, 16000)
    
  13. ==============================

    13.난 그냥 벤의 위대한 대답 밖으로 SP를 만들었습니다 :

    난 그냥 벤의 위대한 대답 밖으로 SP를 만들었습니다 :

    /*
    ---------------------------------------------------------------------------------
    PURPOSE   : Print a string without the limitation of 4000 or 8000 characters.
    https://stackoverflow.com/questions/7850477/how-to-print-varcharmax-using-print-statement
    USAGE     : 
    DECLARE @Result NVARCHAR(MAX)
    SET @Result = 'TEST'
    EXEC [dbo].[Print_Unlimited] @Result
    ---------------------------------------------------------------------------------
    */
    ALTER PROCEDURE [dbo].[Print_Unlimited]
        @String NVARCHAR(MAX)
    AS
    
    BEGIN
    
        BEGIN TRY
        ---------------------------------------------------------------------------------
    
        DECLARE @CurrentEnd BIGINT; /* track the length of the next substring */
        DECLARE @Offset TINYINT; /* tracks the amount of offset needed */
        SET @String = replace(replace(@String, CHAR(13) + CHAR(10), CHAR(10)), CHAR(13), CHAR(10))
    
        WHILE LEN(@String) > 1
        BEGIN
            IF CHARINDEX(CHAR(10), @String) BETWEEN 1 AND 4000
            BEGIN
                SET @CurrentEnd =  CHARINDEX(CHAR(10), @String) -1
                SET @Offset = 2
            END
            ELSE
            BEGIN
                SET @CurrentEnd = 4000
                SET @Offset = 1
            END   
            PRINT SUBSTRING(@String, 1, @CurrentEnd) 
            SET @String = SUBSTRING(@String, @CurrentEnd + @Offset, LEN(@String))   
        END /*End While loop*/
    
        ---------------------------------------------------------------------------------
        END TRY
        BEGIN CATCH
            DECLARE @ErrorMessage VARCHAR(4000)
            SELECT @ErrorMessage = ERROR_MESSAGE()    
            RAISERROR(@ErrorMessage,16,1)
        END CATCH
    END
    
  14. ==============================

    14.여기에 또 다른 버전입니다. 각 문자열은 기본 문자열 대신 (-하지 않도록 후드 매우 긴 문자열을 많이 만들 수 있습니다) 각 루프에 4000의 주요 문자열을 줄여 복용 인쇄이 하나 개 추출합니다.

    여기에 또 다른 버전입니다. 각 문자열은 기본 문자열 대신 (-하지 않도록 후드 매우 긴 문자열을 많이 만들 수 있습니다) 각 루프에 4000의 주요 문자열을 줄여 복용 인쇄이 하나 개 추출합니다.

    CREATE PROCEDURE [Internal].[LongPrint]
        @msg nvarchar(max)
    AS
    BEGIN
    
        -- SET NOCOUNT ON reduces network overhead
        SET NOCOUNT ON;
    
        DECLARE @MsgLen int;
        DECLARE @CurrLineStartIdx int = 1;
        DECLARE @CurrLineEndIdx int;
        DECLARE @CurrLineLen int;   
        DECLARE @SkipCount int;
    
        -- Normalise line end characters.
        SET @msg = REPLACE(@msg, char(13) + char(10), char(10));
        SET @msg = REPLACE(@msg, char(13), char(10));
    
        -- Store length of the normalised string.
        SET @MsgLen = LEN(@msg);        
    
        -- Special case: Empty string.
        IF @MsgLen = 0
        BEGIN
            PRINT '';
            RETURN;
        END
    
        -- Find the end of next substring to print.
        SET @CurrLineEndIdx = CHARINDEX(CHAR(10), @msg);
        IF @CurrLineEndIdx BETWEEN 1 AND 4000
        BEGIN
            SET @CurrLineEndIdx = @CurrLineEndIdx - 1
            SET @SkipCount = 2;
        END
        ELSE
        BEGIN
            SET @CurrLineEndIdx = 4000;
            SET @SkipCount = 1;
        END     
    
        -- Loop: Print current substring, identify next substring (a do-while pattern is preferable but TSQL doesn't have one).
        WHILE @CurrLineStartIdx < @MsgLen
        BEGIN
            -- Print substring.
            PRINT SUBSTRING(@msg, @CurrLineStartIdx, (@CurrLineEndIdx - @CurrLineStartIdx)+1);
    
            -- Move to start of next substring.
            SET @CurrLineStartIdx = @CurrLineEndIdx + @SkipCount;
    
            -- Find the end of next substring to print.
            SET @CurrLineEndIdx = CHARINDEX(CHAR(10), @msg, @CurrLineStartIdx);
            SET @CurrLineLen = @CurrLineEndIdx - @CurrLineStartIdx;
    
            -- Find bounds of next substring to print.              
            IF @CurrLineLen BETWEEN 1 AND 4000
            BEGIN
                SET @CurrLineEndIdx = @CurrLineEndIdx - 1
                SET @SkipCount = 2;
            END
            ELSE
            BEGIN
                SET @CurrLineEndIdx = @CurrLineStartIdx + 4000;
                SET @SkipCount = 1;
            END
        END
    END
    
  15. ==============================

    15.이것은이 이전 응답의 단지 개선이 제대로 작동합니다.

    이것은이 이전 응답의 단지 개선이 제대로 작동합니다.

    DECLARE @Counter INT
    DECLARE @Counter1 INT
    SET @Counter = 0
    SET @Counter1 = 0
    DECLARE @TotalPrints INT
    SET @TotalPrints = (LEN(@QUERY) / 4000) + 1
    print @TotalPrints 
    WHILE @Counter < @TotalPrints 
    BEGIN
    -- Do your printing...
    print(substring(@query,@COUNTER1,@COUNTER1+4000))
    
    set @COUNTER1 = @Counter1+4000
    SET @Counter = @Counter + 1
    END
    
  16. ==============================

    16.소스 코드를 CRLF로 대체 될 LF에 문제가되지 않습니다 경우, 디버깅은 간단한 코드 출력에 따라 필요하지 않습니다.

    소스 코드를 CRLF로 대체 될 LF에 문제가되지 않습니다 경우, 디버깅은 간단한 코드 출력에 따라 필요하지 않습니다.

    --http://stackoverflow.com/questions/7850477/how-to-print-varcharmax-using-print-statement
    --Bill Bai
    SET @SQL=replace(@SQL,char(10),char(13)+char(10))
    SET @SQL=replace(@SQL,char(13)+char(13)+char(10),char(13)+char(10) )
    DECLARE @Position int 
    WHILE Len(@SQL)>0 
    BEGIN
    SET @Position=charindex(char(10),@SQL)
    PRINT left(@SQL,@Position-2)
    SET @SQL=substring(@SQL,@Position+1,len(@SQL))
    end; 
    
  17. from https://stackoverflow.com/questions/7850477/how-to-print-varcharmax-using-print-statement by cc-by-sa and MIT license