[sql] Print Statement를 사용하여 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)

Script의 길이는 약 10,000 자이고 최대 8000 개까지만 담을 수있는 print Statement를 사용하고 있으므로 두 개의 print 문을 사용하고 있습니다.

문제는 내가 18000 자라고하는 스크립트가있을 때 3 개의 print 문을 사용하는 것입니다.

그렇다면 스크립트의 길이에 따라 인쇄 문 수를 설정할 수있는 방법이 있습니까?



답변

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

예 :

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


답변

나는 그것이 오래된 질문이라는 것을 알고 있지만 내가 한 일은 여기에 언급되지 않았습니다.

나를 위해 다음이 작동했습니다.

DECLARE @info NVARCHAR(MAX)

--SET @info to something big

PRINT CAST(@info AS NTEXT)


답변

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

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

반환 된 XML을 클릭하여 내장 XML 뷰어에서 확장 할 수 있습니다.

표시되는 크기에는 클라이언트 측 제한이 상당히 넉넉합니다. Tools/Options/Query Results/SQL Server/Results to Grid/XML data필요한 경우 조정으로 이동하십시오 .


답변

이를 수행하는 방법은 다음과 같습니다.

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 에서 가져옴


답변

이 질문을 발견하고 더 간단한 것을 원했습니다 … 다음을 시도하십시오.

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


답변

이 프로시 저는 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


답변

나는 대부분의 사람들이 비슷한 이유로 print를 사용하고 있다고 상상하면서 print 문을 사용하여 동적 SQL을 디버깅하려고했습니다.

나열된 몇 가지 솔루션을 시도한 결과 Kelsey의 솔루션이 사소한 tweeks (@sql은 내 @script 임)에서 작동 함을 발견했습니다. nb LENGTH는 유효한 함수가 아닙니다.

--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)

이 코드는 주석 처리 된대로 출력에 새 줄을 추가하지만 디버깅을 위해서는 문제가되지 않습니다.

Ben B의 솔루션은 완벽하고 가장 우아하지만 디버깅에는 많은 코드 줄이 필요하므로 Kelsey의 약간 수정을 사용하기로 선택했습니다. 한 줄로 재사용하고 호출 할 수있는 Ben B의 코드에 대해 msdb에 저장 프로 시저와 같은 시스템을 만드는 것이 가치가있을 수 있습니까?

안타깝게도 Alfoks의 코드는 더 쉬웠을 것이기 때문에 작동하지 않습니다.