我想为在 MS Azure Synapse 中存储为 varchar(max) 的匹配标记提取 XML 值

Posted

技术标签:

【中文标题】我想为在 MS Azure Synapse 中存储为 varchar(max) 的匹配标记提取 XML 值【英文标题】:I want to extract a XML value for a matching tag stored as varchar(max) in MS Azure Synapse 【发布时间】:2021-09-10 18:20:39 【问题描述】:

我是新 Azure,之前使用的是 SAS,现在我们正在转向 azure synapse 在当前环境下 我想提取存储在 C 列(varcharmax)中的 XML 标记值作为变量。 [数据集][1] [1]:https://i.stack.imgur.com/tbSIF.png 下面的 XML 保存在 C 列(PKDATA)中

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns2:DataSet xmlns:ns2="http://www.test.com/t/cn/el">
    <EnumObject>
        <name>Inpatient</name>
        <value>262784067</value>
        <radiobutton>false</radiobutton>
    </EnumObject>
    <StringObject>
        <name>xxx</name>
        <prompt></prompt>
        <value>/widget.jsp</value>
        <width>99</width>
    </StringObject>
</ns2:DataSet>

如果名称是 Inpatient,则 262784067 作为 Inpatient 类型

输出

|一个 |乙|住院类型 | | 11212 | 2587140 | 262784067 |

我使用了以下代码 选择 a,b, pkdata.value('/EnumObject/name') 作为住院病人类型 来自 dbo.extdata

我收到以下错误 找不到列“pkkddata”或用户定义的函数或聚合“pkdata.value”,或者名称不明确。

我尝试使用以下查询,但给了我错误消息 104220,级别 16,状态 1,第 26 行找不到数据类型“xml”。 SELECT a,b,(pkdata).value('(/EnumObject/name/text())[1]', 'varchar(100)') FROM [dbo].extdata CROSS APPLY (SELECT CAST(pkdata AS xml) ) AS x(pkdata)

当我使用以下代码时出现以下错误 XMLDT 方法“节点”只能在 xml 类型的列上调用。我尝试使用以下内容,但在通过 select x.* from [dbo].[EXTDATA] rt cross join xmltable( '/EnumObject/name' passing xmltype(rt.pkdata) columns name number path 'name/@值') x

不知道如何继续

Azure SQL 版本 Microsoft Azure SQL 数据仓库 - 10.0.16003.0 Apr 28 2021 04:55:16 版权所有 (c) Microsoft Corporation

【问题讨论】:

【参考方案1】:

Azure Synapse Analytics,特别是专用的 SQL 池不支持 XML 数据类型或其附带的任何函数,包括 FOR XML.nodes.value.query.modify 等。

如果您需要这种类型的处理,您可以使用传统的 SQL Server,例如 SQL Server 2019 或 Azure SQL DB。一种选择是使用 Synapse Pipelines 将数据移动到那里。作为替代方案,您可以考虑使用 Synapse Notebooks 和一些自定义 Python / Scala / c# 代码,但我只对此做了一个简单的测试。

Scala 中的简单示例:

单元格 1

// Get the table with the XML column from the database and expose as temp view
val df = spark.read.synapsesql("yourPool.dbo.someXMLTable")

df.createOrReplaceTempView("someXMLTable")

细胞 2

%%sql
-- Use SparkSQL to interrogate the XML
-- https://spark.apache.org/docs/2.3.0/api/sql/index.html#xpath
SELECT
    colA,
    colB,
    xpath_string(pkData,'/DataSet/EnumObject[name="Inpatient"]/value') xvalue
FROM someXMLTable

细胞 3

val df2 = spark.sql(""" 
SELECT
    colA,
    colB,
    xpath_string(pkData,'/DataSet/EnumObject[name="Inpatient"]/value') xvalue
FROM someXMLTable
""")

df2.show

细胞 4

// Write that dataframe back to the dedicated SQL pool
df2.write.synapsesql("yourPool.dbo.someXMLTable_processed", Constants.INTERNAL)

示例笔记本的屏幕截图:

XML 现在有点过时了——您是否考虑过切换到 JSON?此外,如果您的数据量不是很大,那么仅使用 Azure SQL DB 而不是 Synapse 会便宜很多。

【讨论】:

感谢您的回复,它让我明白了很多事情,非常感谢在这个基本级别上进行解释。我无权访问 Azure 堆栈来创建 Synapse Notebook 实例。 SQL server Management Studio 是我机器上安装的唯一工具。所以我必须升级这个 老实说,我不确定 Azure Synapse 是否适合进行 XML 处理 - 请考虑我提到的替代方案。

以上是关于我想为在 MS Azure Synapse 中存储为 varchar(max) 的匹配标记提取 XML 值的主要内容,如果未能解决你的问题,请参考以下文章

Azure 数据工厂中的 Azure Synapse 存储过程:是同步调用吗?

Azure Synapse 可以从外部关系存储中查询吗?

通过托管标识通过 Synapse 访问 Azure 存储帐户

将 Parquet 文件从 Azure 数据湖存储帐户复制到 Synapse 数据仓库表失败

为啥 Azure Synapse 将存储节点大小限制为 60?

使用 ADF 将 azure blob 文件复制到 azure synapse