我正在处理包含多种数据类型的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) NULL,
[contentModel_id] [int] NULL,
[site_settings] [xml] NULL
);
以下是[site_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>
示例2:
<settings>
<s key="isvisionimpaired" type="Bit" value="0" />
<s key="insurancerequesturl" type="String" value="" />
<s key="haswheelstudio" type="Bit" value="0" />
<s key="hasironfunnel" type="Bit" value="0" />
<s key="haselasticsearch" type="Bit" value="0" />
<s key="hasinventorynotifier" type="Bit" value="0" />
<s key="themeconfigurationjson" type="String" value="{&quot;siteHeader&quot;:{&quot;scheme&quot;:&quot;light&quot;,&quot;headerLinks&quot;:false,&quot;navType&quot;:&quot;expanded&quot;},&quot;body&quot;:{&quot;grid&quot;:&quot;compact&quot;},&quot;siteFooter&quot;:{&quot;scheme&quot;:&quot;light&quot;},&quot;logo&quot;:{&quot;enabled&quot;:true,&quot;imageUrl&quot;:&quot;//cdnmedia.example.com/images/organizations/7a1fd181-1154-4cb6-8c43-a6f354b9f824/logo/dealer-logo.gif?v=1455044570132&quot;}}" />
<s key="hasautoquote" type="Bit" value="0" />
<s key="usesimplequoteform" type="Bit" value="1" />
<s key="overrideinventorysearchtitle" type="Bit" value="1" />
<s key="overrideshowcasetitle" type="Bit" value="1" />
<s key="financingexternalurl" type="String" value="" />
<s key="disablemakeofferrequest" type="Bit" value="0" />
<s key="enablereceiveoffers" type="Bit" value="1" />
<s key="vehiclehistoryurl" type="String" value="" />
<s key="displayinstocknotifier" type="Bit" value="1" />
<s key="disableautoresponseemail" type="Bit" value="0" />
<s key="enablesolditemsremoval" type="Bit" value="0" />
<s key="usefinancingexternalurl" type="Bit" value="0" />
</settings>
从上面的示例中可以看出,xml列在行与行之间不是很一致,并且不显示所有&#34;键&#34;。 (注意,我没有设计这个数据库。)
我想创建一个显示所有列的视图,还要从[site_settings]列的xml结构中提取一些值,并在我的视图中将它们显示为新列。我认为我们的xml有点时髦,因为我尝试这样做的所有例子都没有找到我。
这就是我想要的东西:
CREATE VIEW [vw_Sites]
AS
SELECT
[site_id], [organization_id],
[site_creationDate], [site_active], [site_activatedBy],
[contentModel_id], [hasinventorynotifier],
[displayinstocknotifier], [usesimplequoteform],
[isvisionimpaired] (and more xml keys, etc...)
FROM
[sites] WITH (NOLOCK)
GO
我已尝试通过在下面的这些查询中选择列的值来提取一些提取方法,但结果会返回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)
答案 0 :(得分:1)
这是一种将所有值以 输出的方法:
您的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);
另一种方法可能是 - 如果你知道所有可能的数据 - 一个接一个地写下所有数据:
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
在这种情况下,缺失的值只会返回空...
优势:您可以指定正确的数据类型并使用“发言”列名称(在您的情况下可能是密钥的名称)。
第三种方法可能是动态SQL,您可以使用 中的所有信息生成语句,以生成与上面完全相同的语句。这样做可以动态指定列名和数据类型。
最后,您需要一个EXEC
,这使得无法将此方法集成到诸如VIEW之类的即席查询中。
根据你的评论
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]