在 SQL Server 中将数据转换为 XML 时出错
Posted
技术标签:
【中文标题】在 SQL Server 中将数据转换为 XML 时出错【英文标题】:Error when converting data to XML in SQL Server 【发布时间】:2019-09-13 13:39:49 【问题描述】:我需要检索 View 表中逗号分隔字符串的位置 10 中的内容。
Row 1 N,l,S,T,A,,<all>,,N,A,N,N,N,Y,Y,,Y,Y,Y,,AA,SA,Enterprise,
Row 2 M,,A,S,AS,SS,AS,N,N,N,N,Y,Y,Y,ENTERPRISE,S,,A
Row 3 L,,A,D,S,A,A,AA,Y,Y,Y,YNN,N,N,N,N,A,AA,AD,D,D
Div1 是我的列的名称,Div2 是结果列的名称。我使用以下代码:
SELECT TOP (2000)
[Id],
CONVERT(XML,'<x>' + REPLACE(REPLACE(REPLACE(Div1, '>', ''), '<', ''), ',', '</x <x>') + '</x>').value('/x[10]', 'VARCHAR(MAX)') [Div2],
Div1
FROM
[dbo].[database]
我使用字符类型VARCHAR(MAX)
,因为这是我数据库中 Div1 的类型。如果我运行的行数少于 20000,则该代码有效。但是我使用的数据集有超过 100,000 行。如果我运行整个数据,它会停止并出现以下错误:
消息 9421,第 16 级,状态 1,第 1 行。 XML解析:第1行,字符218,非法名称字符
有没有办法解决这个问题?
【问题讨论】:
要检索逗号分隔字符串的位置 10 中的内容,您不需要将字符串转换为 xml。您可以找到大量 SQL 示例来将 csv 字符串转换为结果集。 您的 SQL Server 版本是多少? 谢谢,我的 SQL Server Management Studio 版本是 15.0.18142.0 【参考方案1】:XML 具有 CDATA[] 部分,无需解析即可按原样处理内容。不需要多个 REPLACE() 函数调用。看看吧。
SQL
-- DDL and sample data population, start
DECLARE @tbl TABLE (ID INT IDENTITY(1,1) PRIMARY KEY, Div1 VARCHAR(MAX));
INSERT INTO @tbl (Div1)
VALUES
('N,l,S,T,A,,<all>,,N,A,N,N,N,Y,Y,,Y,Y,Y,,AA,SA,Enterprise')
, ('M,,A,S,AS,SS,AS,N,N,N,N,Y,Y,Y,ENTERPRISE,S,,A')
, ('L,,A,D,S,A,A,AA,Y,Y,Y,YNN,N,N,N,N,A,AA,AD,D,D');
-- DDL and sample data population, end
SELECT [Id],
CAST('<x><![CDATA[' + REPLACE(Div1, ',', ']]></x><x><![CDATA[') + ']]></x>' AS XML).value('(/x/text())[10]', 'VARCHAR(MAX)') [Div2],
Div1
FROM @tbl;
【讨论】:
好答案,我这边+1。 它在 value() 处略有变化时起作用。由于某种原因,如果我改变了位置,则值不正确。我的字符串很长,这只是一个摘录。看:SELECT [LacNo], CAST('您可以创建一个函数来拆分字符串,如下所示:
CREATE FUNCTION dbo.split_delimited_string
(
@list varchar(max),
@delimiter varchar(5)
)
RETURNS @items TABLE
(
pos_id int identity(1,1),
item varchar(255)
)
AS
BEGIN
DECLARE @pos int, @delimiter_len tinyint;
SET @pos = CHARINDEX(@delimiter,@list);
SET @delimiter_len=LEN(@delimiter);
WHILE (@pos>0)
BEGIN
INSERT INTO @items (item)
SELECT LEFT(@list,@pos - 1)
SET @list = RIGHT(@list,LEN(@list) - @pos - @delimiter_len + 1);
SET @pos = CHARINDEX(@delimiter,@list);
END
IF @list<>N''
BEGIN
INSERT INTO @items (item)
SELECT @list;
END
RETURN;
END
以下查询将返回第 10 位的内容:
SELECT
t.[Id],
l.item AS Div2
t.Div1
FROM [dbo].[database] t
CROSS APPLY dbo.split_delimited_string(t.Div1,',') l
WHERE l.pos_id = 10;
【讨论】:
以上是关于在 SQL Server 中将数据转换为 XML 时出错的主要内容,如果未能解决你的问题,请参考以下文章
在 SQL Server 2008 中将 NVARCHAR 转换为 INT 数据类型