LIKE语句中的4000个字符限制

Jon*_*anN 3 sql sql-server ssrs-2008

我在SSRS报告调用的以前工作的存储过程中遇到错误,我已将其跟踪到存储过程调用的标量函数中的LIKE语句,并结合7000+ NVARCHAR(MAX)字符串.它类似于:

Msg 8152, Level 16, State 10, Line 14
String or binary data would be truncated.

我可以使用以下代码重现它:

DECLARE @name1 NVARCHAR(MAX) = ''
DECLARE @name2 NVARCHAR(MAX) = ''
DECLARE @count INT = 4001
WHILE @count > 0
    BEGIN
        SET @name1 = @name1 + 'a'
        SET @name2 = @name2 + 'a'
        SET @count = @count - 1
    END

SELECT LEN(@name1)

IF @name1 LIKE @name2
    PRINT 'OK'
Run Code Online (Sandbox Code Playgroud)

这是怎么回事?反正有这个限制,还是有充分的理由?谢谢.

Aar*_*and 6

您还可以在没有可怕循环的情况下重现它:

DECLARE @name1 NVARCHAR(MAX), @name2 NVARCHAR(MAX);

SET @name1 = REPLICATE(CONVERT(NVARCHAR(MAX), N'a'), 4000);
SET @name2 = @name1;

IF @name1 LIKE @name2
  PRINT 'OK';

SELECT @name1 += N'a', @name2 += N'a';

IF @name1 LIKE @name2
  PRINT 'OK';
Run Code Online (Sandbox Code Playgroud)

结果:

OK
消息8152,级别16,状态10,行30
字符串或二进制数据将被截断.

在任何情况下,原因都LIKE(强调我的)文件中明确说明:

match_expression [NOT] LIKE模式[ESCAPE escape_character]

...

pattern

是要在match_expression中搜索的特定字符串,并且可以包含以下有效通配符.模式最多可以是8,000个字节.

并且4,000个字符使用了8,000个字节.

我建议比较前4,000个字符可能就足够了:

WHERE column LIKE LEFT(@param, 4000) + '%';
Run Code Online (Sandbox Code Playgroud)

我无法想象你想要比较整个事物的任何场景; 多少个字符串包含相同的前4000个字符,但字符4001是不同的?如果这确实是一个要求,我想你可以在David指出的Connect项目中找到很长的篇幅.

一个更简单(虽然计算成本更高)的解决方法可能是:

IF CONVERT(VARBINARY(MAX), @name1) = CONVERT(VARBINARY(MAX), @name2)
  PRINT 'OK';
Run Code Online (Sandbox Code Playgroud)

我建议通过比较大字符串来修复设计并停止识别行会好得多.真的没有办法确定你所追求的那一行吗?这就像在停车场找到你的车一样,通过测试所有杯架中所有Dunkin甜甜圈杯的DNA,而不仅仅是检查车牌.