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语句?
任何建议都会受到热烈赞赏。
答案 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