将xml中的数据提取到SQL Server表中

Posted

技术标签:

【中文标题】将xml中的数据提取到SQL Server表中【英文标题】:Extracting data from xml into SQL server table 【发布时间】:2020-10-16 12:39:57 【问题描述】:

我的 xml 格式如下:

[My company customer detail - Account ID <3116131311616116>, Subscriber Name <Jon>, Age <52>, Phone <>, Payment<CC>]

我无法将数据从 xml 传输到 SQL Server 表列。列名称,例如 Account ID、Subscriber Name、Age、Phone、Payment

上面提到的 xml 细节看起来像字符串。 XML(String) 在如下列中: enter image description here

我需要从详细列中提取数据并将数据推送到具有来自 xml/string 的属性的新表中。

【问题讨论】:

在我看来这不像 XML。你试过什么了?您的 XML 是如何提供的(平面文件,可以从另一个数据库查询的数据)?它总是具有相同的格式吗?您正在处理多少 XML? 那绝对是不是 XML 数据。我不知道它是什么意思,但我建议将它消耗到数据集中的任何东西都是不是 SQL Server。无论您使用哪种语言,它都需要具有良好的字符串操作并且最好支持 REGEX; SQL Server 两者都不提供。 SQL Server 版本是多少? 详细信息以列的形式在表格中,在我看来,上面提到的所需 xml 似乎比 xml 更多。 您的 SQL Server 版本是多少? 【参考方案1】:

这是一个不限于“列”数量的超级骗子:

-- Data mock-up.
DECLARE @value VARCHAR(500) = '[My company customer detail - Account ID <3116131311616116>, Subscriber Name <Jon>, Age <52>, Phone <>, Payment<CC>]';

-- Construct the dynamic SQL field/value list.
DECLARE @sql VARCHAR(MAX);
SELECT @sql = ISNULL( @sql, '' ) 
    + ', ' + QUOTENAME( SUBSTRING( value, CHARINDEX( '<', value ) + 1, CHARINDEX( '>', value ) - CHARINDEX( '<', value ) - 1 ), '''' )
    + ' AS [' + LTRIM( RTRIM( LEFT( value, CHARINDEX( '<', value ) - 1 ) ) ) + ']'
FROM STRING_SPLIT( REPLACE( REPLACE( @value, ']', '' ), '[', '' ), ',' )

-- Complete the dynamic SQL.
SET @sql = 'SELECT ' + STUFF( @sql, 1, 2, '' ) + ';';

-- Print the resulting dynamic SQL.
PRINT @sql;

-- Execute the dynamic SQL.
EXEC( @sql );

打印显示:

SELECT '3116131311616116' AS [My company customer detail - Account ID], 'Jon' AS [Subscriber Name], '52' AS [Age], '' AS [Phone], 'CC' AS [Payment];

执行返回:

+-----------------------------------------+-----------------+-----+-------+---------+
| My company customer detail - Account ID | Subscriber Name | Age | Phone | Payment |
+-----------------------------------------+-----------------+-----+-------+---------+
|                        3116131311616116 | Jon             |  52 |       | CC      |
+-----------------------------------------+-----------------+-----+-------+---------+

【讨论】:

【参考方案2】:

通过“将数据从 xml 传输到 SQL 服务器表列”我假设您的意思是插入到 sql 服务器表。如果是这样,这意味着解析 xml 是在应用程序中完成的,然后您应该以 insert..values 的形式构造一个字符串,但显然需要更多信息。 另一种选择是将 xml 作为输入参数传递给存储过程,在过程中解析 xml 并插入表。 您提供的信息越多,将有助于更好地回答您的问题。 这两个选项是有效的,这是设计和偏好的问题。一般来说,如果您要处理的 xml 很大,则首选在应用程序中进行解析。

【讨论】:

嗨 Yaniv,在我看来,细节更像是字符串。我正在从似乎是 xml 但不是 xml 格式的表列中提取详细信息。【参考方案3】:

你可以使用这样的查询

SELECT CAST([XMLData] AS XML).value('(/MyCompany/AccountID)[1]', 'VARCHAR(MAX)') AS "Account ID",
       CAST([XMLData] AS XML).value('(/MyCompany/SubscriberName)[1]', 'VARCHAR(MAX)') AS "Subscriber Name",
       CAST([XMLData] AS XML).value('(/MyCompany/Age)[1]', 'VARCHAR(MAX)') AS "Age",
       CAST([XMLData] AS XML).value('(/MyCompany/Phone)[1]', 'VARCHAR(MAX)') AS "Phone",
       CAST([XMLData] AS XML).value('(/MyCompany/Payment)[1]', 'VARCHAR(MAX)') AS "Payment"
  FROM tab 

假设您在VARCHAR 类型的表中有一个列[XMLData],其值为

<MyCompany>
  <AccountID>3116131311616116</AccountID>
  <Phone></Phone>
  <Age>52</Age>
  <SubscriberName>Jon</SubscriberName>
  <Payment>CC</Payment>
</MyCompany>

取决于提供的数据。

如果列的类型为XML,则不需要强制转换,例如用作[XMLData].value

Demo

【讨论】:

您好,Barbaros,感谢您的帮助。我的详细数据不是 xml 格式,它更多的是字符串。我需要提取属性并将数据推送到表中。【参考方案4】:

请尝试以下解决方案。

首先,将乱码字符串转换为 XML。当它是 XML 的那一刻,其余的都是微不足道的。

SQL

DECLARE @unstructured VARCHAR(max) = '[My company customer detail - Account ID <3116131311616116>, Subscriber Name <Jon>, Age <52>, Phone <>, Payment<CC>]';

DECLARE @separator CHAR(1) = '>'
    , @lt CHAR(1) = '<';

;WITH rs AS
(
    SELECT TRY_CAST('<root><r><![CDATA[' + 
                REPLACE(@unstructured, @separator, ']]></r><r><![CDATA[') + 
               ']]></r></root>' AS XML) AS xmldata
), cte AS
(
    SELECT c.value('(r[1]/text())[1]','VARCHAR(100)') AS col1
        , c.value('(r[2]/text())[1]','VARCHAR(30)') AS col2
        , c.value('(r[3]/text())[1]','VARCHAR(30)') AS col3
        , c.value('(r[4]/text())[1]','VARCHAR(30)') AS col4
        , c.value('(r[5]/text())[1]','VARCHAR(30)') AS col5
    FROM rs CROSS APPLY xmldata.nodes('/root') AS t(c)
)
SELECT STUFF(col1, 1, CHARINDEX(@lt, col1,1), '') AS AccountID
    , STUFF(col2, 1, CHARINDEX(@lt, col2,1), '') AS SubscriberName
    , STUFF(col3, 1, CHARINDEX(@lt, col3,1), '') AS Age
    , STUFF(col4, 1, CHARINDEX(@lt, col4,1), '') AS Phone
    , STUFF(col5, 1, CHARINDEX(@lt, col5,1), '') AS Payment
FROM cte;

输出

+------------------+----------------+-----+-------+---------+
|    AccountID     | SubscriberName | Age | Phone | Payment |
+------------------+----------------+-----+-------+---------+
| 3116131311616116 | Jon            |  52 |       | CC      |
+------------------+----------------+-----+-------+---------+

【讨论】:

以上是关于将xml中的数据提取到SQL Server表中的主要内容,如果未能解决你的问题,请参考以下文章

从sql server中的xml中提取数据

从 SQL Server 中的 XML 数据类型字段中提取数据

将 XML 数据保存到 SQL Server 表

sql server如何如何从一个表中提取部分资讯插入到另一表中

如何使用 SSIS 将 OTM 中的数据提取到 SQL Server 中?

如何在 C# 控制台应用程序中使用 XmlTextReader 将 XML 数据插入 SQL Server 表?