T-SQL VARCHAR(MAX)截断

时间:2011-09-12 18:23:13

标签: tsql

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

EDITED

EXECUTE语句是否会将字符串截断为8,000个字符,例如PRINT?如何执行具有8,000多个字符的动态SQL语句?

任何建议都会受到热烈赞赏。

6 个答案:

答案 0 :(得分:13)

PRINT的输出限制为8k。

SSMS结果窗格中还有8k限制。

转到

工具 - >选项 - >查询结果

查看选项。

要验证实际数据的长度,请检查:

SELECT LEN(@str)

答案 1 :(得分:4)

当连接字符串并且结果是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 :(得分:2)

varchar的{​​{3}}为30个字符:

CAST (ID AS VARCHAR) 

id是否可能超过30个字符?

答案 3 :(得分:2)

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个执行语句都会运行(警告,可能需要几分钟!)

答案 4 :(得分:0)

当你连接文字时,如果一个文件不是一个varchar(max),结果就是&#34;隐式转换&#34;到varchar(8000)。

要生成文字varchar(max),所有部分必须为varchar(max)。 注意:碰巧我对varchar(max)列进行了更新,从未使用EXEC命令进行测试。

同样如前面的答案所述,print命令有一个限制,但您可以尝试选择该变量而不是打印它。 (也是您可以在MS-SMS上配置的选择长度的限制)

答案 5 :(得分:0)

我还想看看我发送给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