我在SQL表列中有以下XML数据:
<root>
<Physicians>
<name></name>
<picture></picture>
<gender></gender>
<langAccept>English</langAccept>
<langAccept>Spanish</langAccept> (can appear more times)
<insAccept>Aetna</insAccept>
<insAccept>BCBS</insAccept> (can appear more times)
<specialty></specialty>
<specialty2></specialty2>
<specialty3></specialty3>
</Physicians>
</root>
langAccept
和insAccept
可以多次出现,无法知道多少次。
我有以下SQL查询,目前没有考虑到&#39; langAccept&#39;和&#39; insAccept&#39;标记:
DECLARE @strProvider varchar(200)
SET @strProvider = '' --The Provider DropDownList
DECLARE @strSpecialty varchar(200)
SET @strSpecialty = '' --The Specialty DropDownList
DECLARE @strLocation varchar(200)
SET @strLocation = '' --The Location DropDownList
DECLARE @strGender varchar(200)
SET @strGender = '' --The Gender DropDownList
DECLARE @strInsurance varchar(200)
SET @strInsurance = '' --The Insurance DropDownList
DECLARE @strLanguage varchar(200)
SET @strLanguage = '' --The Language DropDownList
SELECT
[content_title] AS [Physician Name]
, [content_status] AS [Status]
, CAST([content_html] AS XML).value('(root/Physicians/picture/img/@src)[1]','varchar(255)') AS [Image]
, dbo.usp_ClearHTMLTags(CONVERT(nvarchar(600), CAST([content_html] AS XML).query('root/Physicians/gender'))) AS [Gender]
, CAST([content_html] AS XML).query('/root/Physicians/OfficeLocations/office1/a') AS [Office1]
, CAST([content_html] AS XML).query('/root/Physicians/OfficeLocations/office2/a') AS [Office2]
, CAST([content_html] AS XML).query('/root/Physicians/OfficeLocations/office3/a') AS [Office3]
, CAST([content_html] AS XML).query('/root/Physicians/OfficeLocations/office4/a') AS [Office4]
, CAST ([content_html] AS XML).query('/root/Physicians/specialty/a') AS [Specialty1]
, CAST ([content_html] AS XML).query('/root/Physicians/specialty2/a') AS [Specialty2]
FROM
[MYDB].[dbo].[content]
WHERE
[folder_id] = '188'
AND
(content_html LIKE '%<gender>%'+ @strGender+'%</gender>%')
AND
(content_html LIKE '%'+@strSpecialty+'%')
AND
(content_html LIKE '%'+@strLocation+'%')
AND
(content_status = 'A')
ORDER BY
[content_title]
我将使用C#作为代码隐藏,将这些数据写入我的ASP.net页面中的转发器。
如何修改我的SQL查询,使其获取每个langAccept
和insAccept
标记的值(显示的次数)。
答案 0 :(得分:5)
你可以处理可能重复的任意数量的节点 - 但请注意,这将始终为单个条目<Physician>
创建大量行。
试试这个:
DECLARE @Content TABLE (ID INT NOT NULL, XmlDAta XML)
INSERT INTO @content VALUES(1, '<root>
<Physicians>
<name>Dr. Excellent</name>
<picture></picture>
<gender>Male</gender>
<langAccept>English</langAccept>
<langAccept>Spanish</langAccept>
<insAccept>Aetna</insAccept>
<insAccept>BCBS</insAccept>
<specialty></specialty>
<specialty2></specialty2>
<specialty3></specialty3>
</Physicians>
</root>')
SELECT
ID,
PhysicianName = XC.value('(name)[1]', 'varchar(50)'),
Gender = XC.value('(gender)[1]', 'varchar(50)'),
LangSpoken = XLang.value('.', 'varchar(20)'),
InsAccepted = XIns.value('.', 'varchar(50)')
FROM
@Content
CROSS APPLY
XmlData.nodes('/root/Physicians') AS XT(XC)
CROSS APPLY
XC.nodes('langAccept') AS XT2(XLang)
CROSS APPLY
XC.nodes('insAccept') AS XT3(XIns)
在.nodes()
节点内的langAccept
和insAccept
上使用<Physician>
,您可以获得所有定义的值 - 但最终会得到几个关系行单个<Physican>
节点:
更新:从您自己的现有表中获取数据,请使用:
SELECT
ID,
PhysicianName = XC.value('(name)[1]', 'varchar(50)'),
Gender = XC.value('(gender)[1]', 'varchar(50)'),
LangSpoken = XLang.value('.', 'varchar(20)'),
InsAccepted = XIns.value('.', 'varchar(50)')
FROM
[MyDB].[dbo].Content
CROSS APPLY
CAST(content_html AS XML).nodes('/root/Physicians') AS XT(XC)
CROSS APPLY
XC.nodes('langAccept') AS XT2(XLang)
CROSS APPLY
XC.nodes('insAccept') AS XT3(XIns)
答案 1 :(得分:1)
你可以这样试试。 这不是您问题的确切答案,但这可以帮助您解决问题。
DECLARE @Data XMl = '<root><Physicians><name>sajsj</name><picture/><gender/><langAccept>English</langAccept><langAccept>Spanish</langAccept> (can appear more times)<insAccept>Aetna</insAccept><insAccept>BCBS</insAccept> (can appear more times)<specialty/><specialty2/><specialty3/></Physicians></root>';
;WITH CTE AS (
SELECT Dt.value('(name/text())[1]','VARCHAR(100)') AS Name,
Dt.query('(langAccept)') AS LangAccept,
Dt.query('(insAccept)') AS InsAccept
FROM
@Data.nodes('/root/Physicians') AS MyData(Dt)
),
CteGetAllLangAccept AS
(
SELECT
Ct.Name,
Data.Lang.value('(.)[1]', 'VARCHAR(50)') AS [LangAcceptValue],
NULL AS [InsAcceptDataValue]
FROM CTE Ct
CROSS APPLY Ct.LangAccept.nodes('/langAccept') AS Data(Lang)
),
CteGetInsAcceptData AS (
SELECT
Ct.Name,
NULL AS [LangAcceptValue],
InsAcceptData.Ins.value('(.)[1]', 'VARCHAR(50)') AS [InsAcceptDataValue]
FROM CTE Ct
CROSS APPLY Ct.InsAccept.nodes('/insAccept') AS InsAcceptData(Ins)
)
SELECT * FROM CteGetAllLangAccept![enter image description here][1]
UNION
SELECT * FROM CteGetInsAcceptData;
答案 2 :(得分:1)
我认为如果你想在客户端展示它,就可以更容易地做几个查询,一个用于医生表,一个用于langAccept
,一个用于insAccept
:
declare @temp table (data xml)
insert into @temp (data)
select '<root>
<Physicians>
<name>House M.D.</name>
<picture></picture>
<gender>Male</gender>
<langAccept>English</langAccept>
<langAccept>Spanish</langAccept>
<insAccept>Aetna</insAccept>
<insAccept>BCBS</insAccept>
<specialty></specialty>
<specialty2></specialty2>
<specialty3></specialty3>
</Physicians>
<Physicians>
<name>Paracelsus</name>
<picture></picture>
<gender>Male</gender>
<langAccept>German</langAccept>
<langAccept>Latin</langAccept>
<specialty></specialty>
<specialty2></specialty2>
<specialty3></specialty3>
</Physicians>
</root>'
select
t.c.value('name[1]', 'nvarchar(max)') as name,
t.c.value('gender[1]', 'nvarchar(max)') as gender
from @temp as a
cross apply a.data.nodes('root/Physicians') as t(c)
select
t.c.value('name[1]', 'nvarchar(max)') as name,
l.c.value('.', 'nvarchar(max)') as langAccept
from @temp as a
cross apply a.data.nodes('root/Physicians') as t(c)
cross apply t.c.nodes('langAccept') as l(c)
select
t.c.value('name[1]', 'nvarchar(max)') as name,
l.c.value('.', 'nvarchar(max)') as insAccept
from @temp as a
cross apply a.data.nodes('root/Physicians') as t(c)
cross apply t.c.nodes('insAccept') as l(c)