sql-server - 在混合值表上查询 SQL Server 中 XML 中的值选择
问题描述
我有一张桌子,里面有购买慈善晚会门票的人,这张桌子包含注册活动的详细信息,XML 将显示他们带来的客人,还有任何饮食要求的详细信息,以及偶尔参加活动的人可能被禁用。这应该被推送到我们的 CRM 系统,但目前无法正常工作。
我正在尝试从我们导入表的列中的一些 XML 中提取一些值。
我已经看到很多查询普通 XML 块的示例,但当 XML 位于具有其他正常值INT
和VARCHAR
值的表中时则不然。
我们使用的是 SQL Server 2014。我已经花了几个小时在谷歌上搜索,但对将两者结合在一起的查询毫无头绪。或者即使我应该将 XML 内容推送到一个临时表中,然后我可以与之进行连接。
Declare @xmlstring xml = '<field_import_admin_event_tickets xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<und is_array="true">
<item>
<value>8463</value>
<revision_id>4763</revision_id>
</item>
</und>
</field_import_admin_event_tickets>'
select
MainDataCenter.Col.value('(value)[1]', 'varchar(max)') as Name,
MainDataCenter.Col.value('(revision_id)[1]', 'varchar(max)') as Value
from
@xmlstring.nodes('/field_import_admin_event_tickets/und/item') as MainDataCenter(Col)
^ 这会工作
但我需要同时查询它: -
SELECT *
FROM [importtickets].[bcc].[entityform]
WHERE type LIKE '%show%'
AND createdDATETIME > '2019-03-14'
AND LEN(CAST(field_import_admin_event_tickets AS VARCHAR(MAX)) ) >1
-- bodging a way of seeing if XML code exists or not, doesn't seem to work with IS NOT NULL
AND Jobstatus = 'completed'
我可以粗略地从 XML 中获取值的唯一方法是将其转换为 aVARCHAR
并使用大量 REPLACE 命令去除 XML 标记以将其归结为值。每个 XML 块中可能有 2 到 18 个数值
这是我在 StackOverflow 上的第一篇文章,我花了几天时间搜索这个,所以请对我温柔一点。谢谢。
2019-07-10 嘿,所以我没有完全说清楚。XML 的每一列(少数为空)包含 2 - 34 个单独的数字。我通过将其转换为 VARCHAR 并运行大量替换命令来更好地理解它,从而对数据进行了一些粗略的操作。 这是一些 XML 中最大的例子,34 个整数值,17 个是“值”,17 个是“revision_id” 所以我然后使用大量的 SUBSTRING 将它们全部推送到一个新表中。这是粗略但有效的,但假设每个值都是五位数长(到目前为止)我的老板并不热衷于这个解决方案。 使用 CAST 到 VARCHAR 粗略粉碎 XML 并手动剥离标签 我只需要在每一行中提取的每组值,这样我就可以对它们进行 JOIN 或子查询,其中包含一行或可识别的内容。这些数字将指的是参加某些慈善活动的客人,这些活动将具有一些属性,例如饮食要求或残疾。
解决方案
我不知道,这是否是解决您的问题的最佳方法,但我希望您的问题是正确的,您希望将针对隔离 XML 的工作查询与表格查询结合起来,其中 XML 是内容一列:
首先,我创建了一个有两行的模型
DECLARE @mockupTable TABLE(ID INT IDENTITY,SomeOtherValue VARCHAR(100),YourXml XML);
INSERT INTO @mockupTable(SomeOtherValue,YourXml) VALUES
('This is some value in row 1'
,'<field_import_admin_event_tickets xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<und is_array="true">
<item>
<value>8463</value>
<revision_id>4763</revision_id>
</item>
</und>
</field_import_admin_event_tickets>')
,('This is some value in row 2'
,'<field_import_admin_event_tickets xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<und is_array="true">
<item>
<value>999</value>
<revision_id>888</revision_id>
</item>
</und>
</field_import_admin_event_tickets>');
--查询
SELECT t.ID
,t.SomeOtherValue
,MainDataCenter.Col.value('(value)[1]', 'varchar(max)') as Name
,MainDataCenter.Col.value('(revision_id)[1]', 'varchar(max)') as Value
FROM @mockupTable t
CROSS APPLY t.YourXml.nodes('/field_import_admin_event_tickets/und/item') as MainDataCenter(Col);
结果
ID SomeOtherValue Name Value
1 This is some value in row 1 8463 4763
2 This is some value in row 2 999 888
简而言之:
APPLY
允许逐行调用表值函数。在这种情况下,我们将列的内容(在您的情况下为 XML)提交给内置函数.nodes()
。
与 a 类似,JOIN
我们得到一个连接集,它将列(和行)添加到最终集。我们可以使用该.value()
方法从 XML 中检索实际值。
如果这是最好的方法?我不知道...
您上面的示例仅显示了一个<item>
. .nodes()
将需要返回<item>
派生集中的多个元素。只需一个,直接<item>
使用就可以更轻松地完成.value()
...
推荐阅读
- tensorflow - 从 ImageDataGenerator 中选择 imagenet_utils.preprocess_input 模式的可能性
- laravel - Laravel 收银员定期订阅到期日期
- flutter - 插件 Flutter 上的室内定位系统?
- python - 熊猫:数据框的计算
- ios - CRC16-CCITT 计算
- python - 使用 Python (h5py) 删除外部链接的 HDF5
- macos - NSView的特定圆角
- spring-boot - 从 SAP CloudSDK 获取用于主体传播的 HTTP 客户端究竟需要什么?
- mysql - “已被调用此存储函数/触发器的语句使用”插入后时
- shell - 删除其他输出行中随后出现的字符串