sql - 带有 xml 数据的存储过程

标签 sql sql-server xml

我正在尝试从 SQL Server 表中的字段获取数据。它存储为 xml,我想获取不同行中的每个节点值。 xml示例如下:

<id>{a75f61ce-6627-489f-83bb-d03fc880b764}</id>
<rows>
    <row>
        <columns>
            <column name="ec_date" value="15-November-2017" type="System.DateTime" />
            <column name="ec_amount" value="160" type="System.Decimal" />
            <column name="ec_description" value="viaje en coche" type="System.String" />
            <column name="ec_factura" value="0" type="System.String" />
            <column name="ec_item" value="105.01" type="System.String" />
            <column name="DefaultKey" value="1" type="System.Int32" />
        </columns>
    </row>
    <row>
        <columns>
            <column name="ec_date" value="16-November-2017" type="System.DateTime" />
            <column name="ec_amount" value="2.55" type="System.Decimal" />
            <column name="ec_description" value="2 horas de parkin" type="System.String" />
            <column name="ec_factura" value="0" type="System.String" />
            <column name="ec_item" value="15.04" type="System.String" />
            <column name="DefaultKey" value="2" type="System.Int32" />
        </columns>
    </row>
    <row>
        <columns>
            <column name="ec_date" value="17-November-2017" type="System.DateTime" />
            <column name="ec_amount" value="200" type="System.Decimal" />
            <column name="ec_description" value="taxi a burgos" type="System.String" />
            <column name="ec_factura" value="0" type="System.String" />
            <column name="ec_item" value="15.06" type="System.String" />
            <column name="DefaultKey" value="3" type="System.Int32" />
        </columns>
    </row>
</rows> 

有人可以告诉我如何获取具有不同列值的 sql 行中的每个 < row > 元素吗?

谢谢大家

最佳答案

为了解析表中的 Xml 列,您需要使用 XQuery。以下是如何执行此操作的示例 - 它将为每个 row xml 元素返回一行:

SELECT
    Rows.col.value('(column[@name="ec_date"]/@value)[1]', 
        'DATE') AS EcDate,
    Rows.col.value('(column[@name="ec_amount"]/@value)[1]', 
        'decimal(10,2)') AS EcAmount,
    Rows.col.value('(column[@name="ec_description"]/@value)[1]', 
        'varchar(max)') AS EcDescription
    -- .. etc
FROM
    MyTable mt
    CROSS APPLY
        mt.XmlCol.nodes('//rows/row/columns') 
      AS Rows(col);

(column[@name="ec_date"]/@value)[1] 大致翻译为“找到 name 属性为 value 的第一个列元素ec_date 并返回 value 属性的值。

With a Sql Fiddle here

强制性警告

虽然 xml column 属性名称和类型看起来一致,但数据中似乎嵌入了一个类型系统 - 即尝试提供动态更改列类型的能力会导致这确实很困惑。

另一方面,如果您的 Xml 文档中的所有数据都具有强大的架构,那么我认为 Xml 对于数据建模来说是一个糟糕的选择 - 最好对 row 进入它自己的表。 Xml 是一种冗长的格式,它会重复架构(即浪费空间),并且可能难以解析和过滤。

关于sql - 带有 xml 数据的存储过程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47410677/

相关文章:

c# - 访问/管理多组织的数据库设计

java - org.w3c.dom.Node 的源代码在任何地方都可用吗?

xml - Powershell无法读取xml文件?

mysql - 如何通过一个字段和另一个不匹配的字段匹配(mysql)行

sql - 如果仅存在一个不同的值,则选择不同的值?

mysql - 如何合并两个表,其中一个是另一个的父表?

mysql - 使用 SELECT INTO 后,mariaDB (MySQL) 仍然收到 "Not allowed to return a result set from a function"的错误 1415

python - 使用 sqlalchemy 和 pyodbc 连接到 SQL Server 2012

sql-server - 将列主键和外键 VARCHAR 数据类型更改为 INT 数据类型

javascript - 如何将对象转换为节点