Varchar(Max)在Exec中无法正常工作

6

我有一个变量,其中存储了SQL字符串,并通过exec()执行它。

Declare @sql varchar(max)

set @sql = Concat('select...',@var,'..') -- large string 

exec (@sql)

但是我收到了一个错误,显示:

sometext 附近的语法不正确

这是因为变量 @sql 无法容纳整个字符串。所以我通过将字符串拆分为两个不同的变量并执行来解决它。

Declare @sql1 varchar(max),@sql2 varchar(max)

set @sql1 = 'select...' 
set @sql2 = ' from sometable join....'

exec (@sql1+@sql2)

我检查了@sql1+ @sql2的数据长度。

Select Datalength(@sql1+ @sql2)

它返回了14677

现在的问题是为什么varchar(max)不能存储14677字节的信息?当文档说明它可以存储高达2GB数据时。


1
这很奇怪而且不太可能。你是否使用 select @sql 来检查字符串是否真的正确? - juergen d
2
你可能在 --long string 的地方隐藏了一些罪行,比如使用 + 结合多个短字符串字面量。假设使用 SQL Server 2008 或更高版本,varchar(max) 变量 实际上可以容纳超过 2GB 的数据。 - Damien_The_Unbeliever
@juergend - 是的,当我执行 Select @sql 时,它只返回字符串的一部分。 - Pரதீப்
1
这是我所指的罪名: "如果字符串连接的结果超过 8,000 字节的限制,则结果将被截断。但是,如果连接的字符串中至少有一个是大型值类型,则不会发生截断。" - 如果只有两个字符串字面量,则它们本身都不是大型值类型,而且您最终存储结果的变量也不是方程的一部分。 - Damien_The_Unbeliever
2
好的,CONCAT 的文档也没有什么神秘的地方 - "如果没有任何输入参数是受支持的大型对象(LOB)类型,则返回类型将被截断为8000长度,无论返回类型如何"。如果我们能够看到包含错误的代码,而不是被迫猜测,那么我们更容易指出这些类型的错误。 - Damien_The_Unbeliever
显示剩余7条评论
2个回答

6

可能是你正在遇到这个问题:

DECLARE @part1 VARCHAR(5000)=REPLICATE('a',5000);
DECLARE @part2 VARCHAR(5000)=REPLICATE('a',5000);

SELECT DATALENGTH(@part1),DATALENGTH(@part2),DATALENGTH(@part1+@part2);

结果是 5000,5000,8000 如果其中一个加数是 MAX 类型,您将得到预期的结果。
SELECT DATALENGTH(@part1),DATALENGTH(@part2),DATALENGTH(CAST(@part1 AS VARCHAR(MAX))+@part2);

结果是 5000,5000,10000

这通常与以下情况有关:

  • 字符串连接
  • 使用返回VARCHAR(8000)的(旧)函数,作为以前的最大长度
  • 列定义

使用 CONCAT 的更新操作也是一样的

SELECT DATALENGTH(@part1),DATALENGTH(@part2),DATALENGTH(CONCAT(@part1,@part2));
SELECT DATALENGTH(@part1),DATALENGTH(@part2),DATALENGTH(CONCAT(CAST(@part1 AS VARCHAR(MAX)),@part2));

0

通过创建两个varchar(max)数据元素并通过“exec (@sql1+@sql2)”组合它们的方法是有效的,我很感谢这个建议。我遇到了同样的问题,将来会使用这个技巧。

对于我来说,当尝试执行一个varchar(max)数据元素时,它被截断了。将其拆分为两个varchar(max)数据元素(没有语法更改)并成功执行。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接