T-SQL VARCHAR(MAX) Truncated

后端 未结 6 1608
谎友^
谎友^ 2020-12-19 01:32
DECLARE @str VARCHAR (MAX);

SELECT @str = COALESCE(@str + CHAR(10), \'\') +
       \'EXECUTE CreateDeno \' + CAST(ID AS VARCHAR) 
FROM   GL_To_Batch_Details
WHERE           


        
相关标签:
6条回答
  • 2020-12-19 02:00

    It happens when you concatenate literals if one is not a varchar(max) the result ill be "implicit casted" to varchar(8000).

    To generate a literal varchar(max) all parts must be varchar(max). Note: It happened to me doing updates on varchar(max) columns, never tested with the EXEC command.

    Also as noted in previous answers the print command holds a limit but you can try selecting that variable instead of printing it. (also ther's a limit on that select length you can configure on MS-SMS)

    0 讨论(0)
  • 2020-12-19 02:03

    The PRINT command is certainly limited to 8000 chars, irrespective of the length of the output (or whether it is varchar(max)). To work around this you need to output the string in chunks of <8000 chars


    Update: In answer to your edit, exec doesn't limit the string length. I've put together the following example to show this:

    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)
    

    Running this prints the length as 34892 chars, and all 2000 execute statements do run (be warned, it may take a few mins!)

    0 讨论(0)
  • 2020-12-19 02:08

    PRINT is limited to 8k in output.

    There is also an 8k limit in SSMS results pane.

    Go to

    tools -> options -> query results

    to see the options.

    To verify the length of the actual data, check:

    SELECT LEN(@str)

    0 讨论(0)
  • 2020-12-19 02:12

    When concatenating strings and the result is of type VARCHAR(MAX) and is over 8000 characters, at least one parameter and/or element being used in the concatenation need to be of the VARCHAR(MAX) type otherwise truncation will occur in the resultant string and will not be executable in an EXEC statement.

    Example:

    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;
    

    More information on MSDN.

    "If the result of the concatenation of strings exceeds the limit of 8,000 bytes, the result is truncated. However, if at least one of the strings concatenated is a large value type, truncation does not occur."

    0 讨论(0)
  • 2020-12-19 02:23

    I also wanted to see what I was sending to Exec, and was confused by the PRINT limit. Had to write a proc to print in chunks.

    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 讨论(0)
  • 2020-12-19 02:24

    The default length of a varchar is 30 characters:

    CAST (ID AS VARCHAR) 
    

    Is it possible that id is longer than 30 characters?

    0 讨论(0)
提交回复
热议问题