从sql server中的xml中提取数据

Posted

技术标签:

【中文标题】从sql server中的xml中提取数据【英文标题】:extract data from xml in sql server 【发布时间】:2021-12-23 06:26:11 【问题描述】:

如何从这个 xml 中提取 lastbatchstarted?

谢谢

<event name="xml_deadlock_report" package="sqlserver" timestamp="2021-11-08T13:16:53.648Z">
  <data name="xml_report">
    <value>
      <deadlock>
        <victim-list>
          <victimProcess id="process2bac10daca8" />
        </victim-list>
        <process-list>
          <process id="process2bac10daca8" taskpriority="0" logused="1772" waitresource="PAGE: 7:1:817276 " waittime="185" ownerId="115165741" transactionname="INSERT" lasttranstarted="2021-11-08T15:16:53.440" XDES="0x2bad31fa040" lockMode="U" schedulerid="1" kpid="14480" status="suspended" spid="64" sbid="0" ecid="7" priority="0" trancount="0" lastbatchstarted="2021-11-08T15:16:53.440" lastbatchcompleted="2021-11-08T15:16:53.440" lastattention="1900-01-01T00:00:00.440" clientapp="dfdf" hostname="dfdf" hostpid="3692" isolationlevel="read uncommitted (1)" xactid="115165741" currentdb="7" lockTimeout="4294967295" clientoption1="673316896" clientoption2="128056">
            <executionStack>

我尝试使用此查询,但它不起作用

[XML 数据].value('(/event/data[@name=''xml_report'']/value/process-list/process/@lastbatchstarted)[1]','datetime')

【问题讨论】:

您在查询路径中缺少/deadlock/ 提问时,您需要提供minimal reproducible example: (1) DDL 和样本数据填充,即 CREATE 表和 INSERT T-SQL 语句。 (2) 你需要做什么,即逻辑和你的代码尝试在 T-SQL 中实现它。 (3) 期望的输出,基于上述#1 中的样本数据。 (4) 您的 SQL Server 版本 (SELECT @@version;)。 【参考方案1】:

没有提供最小的可重现示例。

从臀部射击。

SQL

DECLARE @xml XML = 
N'<event name="xml_deadlock_report" package="sqlserver"
       timestamp="2021-11-08T13:16:53.648Z">
    <data name="xml_report">
        <value>
            <deadlock>
                <victim-list>
                    <victimProcess id="process2bac10daca8"/>
                </victim-list>
                <process-list>
                    <process id="process2bac10daca8" taskpriority="0"
                             logused="1772" waitresource="PAGE: 7:1:817276 "
                             waittime="185" ownerId="115165741"
                             transactionname="INSERT"
                             lasttranstarted="2021-11-08T15:16:53.440"
                             XDES="0x2bad31fa040" lockMode="U" schedulerid="1"
                             kpid="14480" status="suspended" spid="64" sbid="0"
                             ecid="7" priority="0" trancount="0"
                             lastbatchstarted="2021-11-08T15:16:53.440"
                             lastbatchcompleted="2021-11-08T15:16:53.440"
                             lastattention="1900-01-01T00:00:00.440"
                             clientapp="dfdf" hostname="dfdf" hostpid="3692"
                             isolationlevel="read uncommitted (1)"
                             xactid="115165741" currentdb="7"
                             lockTimeout="4294967295" clientoption1="673316896"
                             clientoption2="128056">
                    </process>
                </process-list>
            </deadlock>
        </value>
    </data>
</event>';

SELECT @xml.value('(/event/data[@name="xml_report"]/value/deadlock/process-list/process/@lastbatchstarted)[1]','DATETIME') AS lastbatchstarted;

输出

+-------------------------+
|    lastbatchstarted     |
+-------------------------+
| 2021-11-08 15:16:53.440 |
+-------------------------+

【讨论】:

【参考方案2】:

鉴于您可以在死锁 XML 中拥有多个 process 节点,您可能想要这样的东西

您需要使用.nodes 将节点分解成行

DECLARE @xml XML = 
N'<event name="xml_deadlock_report" package="sqlserver"
       timestamp="2021-11-08T13:16:53.648Z">
    <data name="xml_report">
        <value>
            <deadlock>
                <victim-list>
                    <victimProcess id="process2bac10daca8"/>
                </victim-list>
                <process-list>
                    <process id="process2bac10daca8" taskpriority="0" logused="1772" waitresource="PAGE: 7:1:817276 "
                             waittime="185" ownerId="115165741" transactionname="INSERT"
                             lasttranstarted="2021-11-08T15:16:53.440" XDES="0x2bad31fa040" lockMode="U" schedulerid="1"
                             kpid="14480" status="suspended" spid="64" sbid="0" ecid="7" priority="0" trancount="0"
                             lastbatchstarted="2021-11-08T15:16:53.440" lastbatchcompleted="2021-11-08T15:16:53.440"
                             lastattention="1900-01-01T00:00:00.440" clientapp="dfdf" hostname="dfdf" hostpid="3692"
                             isolationlevel="read uncommitted (1)" xactid="115165741" currentdb="7"
                             lockTimeout="4294967295" clientoption1="673316896" clientoption2="128056">
                    </process>
                </process-list>
            </deadlock>
        </value>
    </data>
</event>';

SELECT
  x.process.value('@lastbatchstarted', 'DATETIME') AS lastbatchstarted,
  x.process.value('@id', 'sysname') AS id,
  x.process.value('@hostname', 'sysname') AS hostname
FROM @xml.nodes('/event/data[@name="xml_report"]/value/deadlock/process-list/process') x(process);

【讨论】:

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

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

从 SQL 中的 XML 数据中提取属性详细信息

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

使用 Oracle 数据库中的 SQL 从 XML Clob 中提取数据

使用SQL Server中的OPENXML解析带有内联架构的XML文件

如何从以 BLOB 类型存储在列中的 XML 中提取数据(通过 SQL 查询)