Как распечатать VARCHAR (MAX) с помощью Print Statement? - PullRequest
87 голосов
/ 21 октября 2011

У меня есть код:

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 символов, я использую два оператора печати. ​​

Проблема в том, что когда у меня есть скрипт, который, скажем, состоит из 18000 символов, я использовал 3 оператора печати. ​​

Так есть ли способ, которым я мог бы установить количество операторов печати в зависимости от длины скрипта?

Ответы [ 15 ]

179 голосов
/ 04 мая 2012

Я знаю, что это старый вопрос, но то, что я сделал, здесь не упоминается.

У меня сработало следующее.

DECLARE @info NVARCHAR(MAX)

--SET @info to something big

PRINT CAST(@info AS NTEXT)
81 голосов
/ 18 апреля 2012

Следующий обходной путь не использует оператор 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, чтобы настроить его, если необходимо.

35 голосов
/ 30 января 2013

Вот как это должно быть сделано:

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

14 голосов
/ 21 октября 2011

Вы могли бы сделать цикл WHILE на основе подсчета длины вашего скрипта, деленной на 8000.

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
10 голосов
/ 07 сентября 2013

Этот процесс правильно печатает параметр 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
9 голосов
/ 04 апреля 2014

Наткнулся на этот вопрос и хотел что-нибудь попроще ... Попробуйте следующее:

SELECT [processing-instruction(x)]=@Script FOR XML PATH(''),TYPE
7 голосов
/ 14 февраля 2013

Я хотел использовать оператор print для отладки некоторых динамических sql, так как я думаю, что большинство из вас использует print по аналогичным причинам.

Я попробовал несколько перечисленных решений и обнаружил, что решение Келси работает снезначительные изменения (@sql - мой @script) nb LENGTH - недопустимая функция:

--/6287510/kak-raspechatat-varchar-max-s-pomoschy-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)

Этот код, как прокомментировано, добавляет новую строку в вывод, но для отладки это не проблемадля меня.

Идея Бена Б идеальна и является наиболее элегантной, хотя для отладки очень много строк кода, поэтому я решил использовать свою небольшую модификацию Келси.Возможно, стоит создать систему, подобную хранимой процедуре в msdb, для кода Бена Б, который можно использовать повторно и вызывать в одну строку?

К сожалению, код Альфокса не работает, потому что это было бы проще.

3 голосов
/ 01 апреля 2017

Вы можете использовать это

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
3 голосов
/ 23 октября 2013
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
2 голосов
/ 01 сентября 2017

Использует перевод строки и пробелы в качестве хорошей точки разрыва:

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 '   '
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...