Sql server 从sql列中的xml提取值和属性
我正在处理一个Microsoft SQL Server表,该表包含多个数据类型,包括一个xml列。例如:Sql server 从sql列中的xml提取值和属性,sql-server,xml,Sql Server,Xml,我正在处理一个Microsoft SQL Server表,该表包含多个数据类型,包括一个xml列。例如: CREATE TABLE [sites] ( [site_id] [int] NOT NULL, [organization_id] [int] NULL, [site_creationDate] [datetime] NULL, [site_active] [bit] NULL, [site_activatedBy] [varchar](20) NU
CREATE TABLE [sites]
(
[site_id] [int] NOT NULL,
[organization_id] [int] NULL,
[site_creationDate] [datetime] NULL,
[site_active] [bit] NULL,
[site_activatedBy] [varchar](20) NULL,
[contentModel_id] [int] NULL,
[site_settings] [xml] NULL
);
以下是[site\u settings]
列中XML的外观:
例1:
<settings>
<s key="hasinventorynotifier" value="0" type="BIT" />
<s key="displayinstocknotifier" value="1" type="BIT" />
<s key="usesimplequoteform" type="BIT" value="1" />
</settings>
我在下面的这些查询中尝试了几种通过选择列的值进行提取的方法,但是结果返回NULL或空白
SELECT
[site_settings].value('usesimplequoteform[1]','bit') AS Test1,
[site_settings].value('settings[1]','varchar(10)') AS Test2,
[site_settings].value('(s[@key="usesimplequoteform"]/@value)[1]','int') AS Test3
FROM
[sites]
或者,我的一位同事建议使用以下案例陈述,这确实有效,但我想知道是否有更好的方法。下面的例子:
SELECT
CASE WHEN CHARINDEX('usesimplequoteform" type="Bit" value="1"',CONVERT(VARCHAR(MAX),site_settings),1) > 0 THEN 1
WHEN CHARINDEX('usesimplequoteform" value="1" type="Bit"',CONVERT(VARCHAR(MAX),site_settings),1) > 0 THEN 1
ELSE 0
END AS useSimpleQuoteForm
FROM [sites]
但是有谁有更好的方法吗?上面的示例仅适用于位变量,其中一些类型为string(varchar)。任何帮助都将不胜感激
输出澄清 基本上,输出将是一个视图,其中包含表[sites]中的所有当前列以及[sites].[site_settings]列中每个键的附加列
[site_id] [organization_id] [site_creationDate] [site_active] [site_activatedBy] [contentModel_id] [hasinventorynotifier] [displayinstocknotifier] [usesimplequoteform] [the keys etc in xml]
5036 4886 2016-01-04 10:16:01.860 1 system 8 1 0 1 (value)
5037 2386 2015-01-05 11:29:23.880 1 system 2 0 0 1 (value)
这是一种按原样获取所有值的方法: 您的XML文件:
DECLARE @xml XML=
'<settings>
<s key="isvisionimpaired" type="Bit" value="0" />
<s key="insurancerequesturl" type="String" value="" />
<s key="haswheelstudio" type="Bit" value="0" />
</settings>'
SELECT a.b.value('@key','varchar(max)') AS s_key
,a.b.value('@type','varchar(max)') AS s_type
,a.b.value('@value','varchar(max)') AS s_value
FROM @xml.nodes('settings/s') AS a(b);
在这种情况下,缺少的值将返回空值
优点:您可以指定正确的数据类型并使用“说话”列名称(在您的情况下,可能是键的名称)
第三种方法可能是动态SQL,您可以使用XML中的所有信息生成语句,以生成与我上面所做的完全相同的语句。这样可以动态指定列名和数据类型
最后,您需要一个EXEC
,这样就不可能在视图等特殊查询中集成这种方法
编辑:这应该是您需要的:
根据你的评论
SELECT *
,[site_settings].value('(/settings/s[@key="isvisionimpaired"]/@value)[1]','bit') AS isvisionimpaired
,[site_settings].value('(/settings/s[@key="insurancerequesturl"]/@value)[1]','varchar(max)') AS insurancerequesturl
,[site_settings].value('(/settings/s[@key="haswheelstudio"]/@value)[1]','bit') AS haswheelstudio
--all possible data here
FROM [sites]
您好,请说明您期望的输出…我添加了一个输出示例。。。基本上,返回所有普通列,但也返回从xml列提取的键值。不过我还是要看看你最近的答案,谢谢!Thx用于输出示例。由于需要将所有列并排放在一行中,因此必须使用我作为第二行使用的方法。看到我编辑的答案了吗?非常感谢!您的第二个代码块示例就是我正在寻找的代码块!我想我真的很接近我的“测试3”专栏的例子,但你为我找到了答案。谢谢@很高兴读到这篇文章!如果您需要关于解码JSON部分的帮助,请提出另一个问题并将链接发到此处。快乐编码@Namkce,是的,你的“测试3”非常接近。只有“/settings/”丢失。。。
DECLARE @xml XML=
'<settings>
<s key="isvisionimpaired" type="Bit" value="0" />
<s key="insurancerequesturl" type="String" value="" />
<s key="haswheelstudio" type="Bit" value="0" />
</settings>'
SELECT a.b.value('@key','varchar(max)') AS s_key
,a.b.value('@type','varchar(max)') AS s_type
,a.b.value('@value','varchar(max)') AS s_value
FROM @xml.nodes('settings/s') AS a(b);
SELECT @xml.value('(/settings/s[@key="isvisionimpaired"]/@value)[1]','bit') AS isvisionimpaired
,@xml.value('(/settings/s[@key="insurancerequesturl"]/@value)[1]','varchar(max)') AS insurancerequesturl
,@xml.value('(/settings/s[@key="haswheelstudio"]/@value)[1]','bit') AS haswheelstudio
--all possible data here
SELECT *
,[site_settings].value('(/settings/s[@key="isvisionimpaired"]/@value)[1]','bit') AS isvisionimpaired
,[site_settings].value('(/settings/s[@key="insurancerequesturl"]/@value)[1]','varchar(max)') AS insurancerequesturl
,[site_settings].value('(/settings/s[@key="haswheelstudio"]/@value)[1]','bit') AS haswheelstudio
--all possible data here
FROM [sites]