【发布时间】:2016-02-04 20:52:16
【问题描述】:
我编写了一个 CTE 代码,它将分隔的字符串(分隔符可以是任何东西)解析到一个表中。所以“MI,TX,WI”会被解析成一个3行的表。
只要我不使用NVARCHAR(MAX) 作为我要解析的字符串输入,它就可以工作。
我想知道如何让它与NVARCHAR(MAX)(或至少VARCHAR(MAX))一起工作?
如果您更改此错误,则除了注释之外,此方法有效:
锚点和列中递归部分的类型不匹配 递归查询“cte”的“b”。
--- change this to NVARCHAR(MAX) and it fails
DECLARE @DelimitedString NVARCHAR(4000)
DECLARE @Delimiter NVARCHAR(10)
SET @Delimiter = '--'
SET @DelimitedString= '123--456--7890, 234--456--7890'
-- do here instead of in every loop below
DECLARE @DelimiterLength AS TINYINT
SET @DelimiterLength = len(@Delimiter)
;with cte as
(
select 0 a, 1 b
union all
select b, charindex(@Delimiter, @DelimitedString, b) + len(@Delimiter)
from cte where b > a
)
select LTRIM(RTRIM(
SUBSTRING(@DelimitedString,
a,
case when b > @DelimiterLength then b-a-@DelimiterLength else len(@DelimitedString) - a + 1 end
)--END SUBSTRING
))--end LTRIM/RTRIM
value
from cte where a > 0
我了解错误在标准中的含义,UNION 数据类型中的列必须匹配。我在这里看不到如何解决此问题。
我希望它可以处理我们需要的任何长度的字符串,因为我不知道使用是否仅限于 4000 个字符的字符串。
【问题讨论】:
-
尝试在 cte 的上半部分将 b 转换为
int。 -
有一些比 ctes 更好的分割字符串的方法。这是一篇专门介绍各种分离器以及它们如何提高性能的整篇文章。无需在这里重新发明轮子。 sqlperformance.com/2012/07/t-sql-queries/split-strings
标签: sql sql-server parsing common-table-expression