如何确保SQL能够读取所有XML标记数据
我在SQL表列中有以下XML数据:
English Spanish (can appear more times) Aetna BCBS (can appear more times)
langAccept
和insAccept
可以多次出现,并且无法知道多少次。
我有以下SQL查询,目前没有考虑’langAccept’和’insAccept’标签:
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 '%%'+ @strGender+'%%') AND (content_html LIKE '%'+@strSpecialty+'%') AND (content_html LIKE '%'+@strLocation+'%') AND (content_status = 'A') ORDER BY [content_title]
我将把这些数据写入我的ASP.net页面中的转发器,使用C#作为代码隐藏。
如何修改我的SQL查询,使其获取每个langAccept
和insAccept
标记的值(显示的次数)。
您可以处理可能重复的任意数量的节点 – 但请注意,这将始终为单个条目
创建多个行。
试试这个:
DECLARE @Content TABLE (ID INT NOT NULL, XmlDAta XML) INSERT INTO @content VALUES(1, ' Dr. Excellent Male English Spanish Aetna BCBS ') 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)
通过在
节点内的langAccept
和insAccept
上使用.nodes()
,可以获得所有已定义的值 – 但最终会为单个
节点提供几个关系行:
更新:要从您自己的现有表中获取数据,请使用以下命令:
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)
你可以这样试试。 这不是您问题的确切答案,但这可能有助于您解决问题。
DECLARE @Data XMl = 'sajsj English Spanish (can appear more times)Aetna BCBS (can appear more times) '; ;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;
我想如果你想在客户端显示它,那么做几个查询会更容易,一个用于医生表,一个用于langAccept
,一个用于insAccept
:
declare @temp table (data xml) insert into @temp (data) select ' House MD Male English Spanish Aetna BCBS Paracelsus Male German Latin ' select tcvalue('name[1]', 'nvarchar(max)') as name, tcvalue('gender[1]', 'nvarchar(max)') as gender from @temp as a cross apply a.data.nodes('root/Physicians') as t(c) select tcvalue('name[1]', 'nvarchar(max)') as name, lcvalue('.', 'nvarchar(max)') as langAccept from @temp as a cross apply a.data.nodes('root/Physicians') as t(c) cross apply tcnodes('langAccept') as l(c) select tcvalue('name[1]', 'nvarchar(max)') as name, lcvalue('.', 'nvarchar(max)') as insAccept from @temp as a cross apply a.data.nodes('root/Physicians') as t(c) cross apply tcnodes('insAccept') as l(c)