T-SQL VARCHAR (MAX) усеченный - PullRequest
       32

T-SQL VARCHAR (MAX) усеченный

9 голосов
/ 12 сентября 2011
DECLARE @str VARCHAR (MAX);

SELECT @str = COALESCE(@str + CHAR(10), '') +
       'EXECUTE CreateDeno ' + CAST(ID AS VARCHAR) 
FROM   GL_To_Batch_Details
WHERE  TYPE = 'C' AND
       Deno_ID IS NULL;

--PRINT @str;--SELECT @str;
**EXEC(@str);**

РЕДАКТИРОВАНИЕ

Сокращает ли оператор EXECUTE строки до 8 000 символов, например PRINT?Как я могу выполнить динамический оператор SQL, имеющий более 8000 символов?

Любое предложение будет тепло оценено.

Ответы [ 6 ]

15 голосов
/ 12 сентября 2011

PRINT ограничен до 8 КБ на выходе.

Существует также ограничение в 8 КБ в области результатов SSMS.

Перейти к

Инструменты -> Параметры -> Результаты запроса

чтобы увидеть опции.

Чтобы проверить длину фактических данных, проверьте:

SELECT LEN(@str)

4 голосов
/ 17 апреля 2015

Если конкатенация строк и результата имеет тип VARCHAR (MAX) и имеет длину более 8000 символов, не менее одного параметра и / или элемента, используемого в конкатенации, должны быть VARCHAR (MAX)тип, иначе усечение произойдет в результирующей строке и не будет выполняться в операторе EXEC.

Пример:

DECLARE @sql AS VARCHAR(MAX);
/* DECLARE @someItem AS VARCHAR(100); -- WILL CAUSE TRUNCATION WHEN @sql HAS LEN > 8000 */
DECLARE @someItem AS VARCHAR(MAX); -- All string variables need to be VARCHAR(MAX) when concatenating to another VARCHAR(MAX)

SET @someItem = 'Just assume the resulting @sql variable goes over 8000 characters...';
SET @sql = 'SELECT Something FROM Somewhere WHERE SomeField = ''' + @someItem + '''';

EXEC (@sql);
--PRINT @sql;

Дополнительная информация о MSDN .

"Если результат объединения строк превышает ограничение в 8 000 байт, результат усекается. Однако, если хотя бы одна из объединенных строк имеет тип большого значения, усечение не происходит. "

2 голосов
/ 12 сентября 2011

Команда PRINT определенно ограничена 8000 символов, независимо от длины вывода (или от того, является ли она varchar (max)).Чтобы обойти это, вам нужно вывести строку в виде кусков <8000 символов


Обновление: в ответ на ваши изменения exec не ограничивает длину строки.Я собрал следующий пример, чтобы показать это:

DECLARE @str VARCHAR (MAX);


;WITH CTE_Count AS
(
    select counter = 1
    union all
    select counter = counter+1
    from CTE_Count
    Where counter < 2000

)
SELECT             
    @str=COALESCE(@str + CHAR (10) ,
        '' ) + 'select value=' + CAST (counter AS VARCHAR) 
from
    CTE_Count

Option (MAXRECURSION 0)

PRINT len(@str);--SELECT @str;

exec (@str)

Выполнение этого печатает длину как 34892 символа, и все 2000 операторов execute выполняются (будьте осторожны, это может занять несколько минут!)

2 голосов
/ 12 сентября 2011

Длина по умолчанию для varchar составляет 30 символов:

CAST (ID AS VARCHAR) 

Возможно ли, что id длиннее 30 символов?

0 голосов
/ 28 июня 2015

Я также хотел посмотреть, что я отправляю в Exec, и был озадачен лимитом PRINT.Пришлось написать процедуру для печати кусками.

CREATE PROCEDURE [dbo].[KFX_PrintVarcharMax] 
    @strMax varchar(max)
AS
BEGIN
    SET NOCOUNT ON;

    DECLARE 
        @index int = 0,
        @start int = 1,
        @blkSize int = 2000;


    WHILE @Start < LEN(@strMax)
    BEGIN
        IF @start + @blkSize >= LEN(@strMax)
        BEGIN
            -- If remainder is less than blocksize print the remainder, and exit.
            PRINT SUBSTRING(@strMax, @start, @blkSize)
            BREAK;
        END
        -- Else find the next terminator (beyond the blksize)
        SET @index = CHARINDEX(CHAR(10), @strMax, @start + @blkSize);
        if @index >= @start
        BEGIN
            PRINT SubString(@strMax, @start, @index - @start + 1)
            SET @start = @index + 1;
            SET @blkSize  = CASE WHEN @start + 2000 < LEN(@strMax) THEN 2000 
                            ELSE LEN(@strMax) - @start + 1 END
        END
        ELSE
        BEGIN
            -- No char(10) found.  Just print the rest.
            PRINT SUBSTRING(@strMax, @start, LEN(@strMax))
            BREAK;
        END 
    END

END
0 голосов
/ 21 октября 2014

Это происходит, когда вы объединяете литералы, если один не является varchar (max), результат будет "неявно приведен" к varchar (8000).

Чтобы сгенерировать литерал varchar (max), все части должны бытьVARCHAR (макс).Примечание: мне случалось делать обновления для столбцов varchar (max), никогда не тестировавшихся с помощью команды EXEC.

Также, как отмечалось в предыдущих ответах, команда печати содержит ограничение, но вы можете попробовать выбрать эту переменную вместо печатиЭто.(также есть ограничение на выбранную длину, которую вы можете настроить в MS-SMS)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...