J'ai XML suivant stocké dans une colonne XML (appelée Roles
) dans une base de données SQL Server.
<root>
<role>Alpha</role>
<role>Beta</role>
<role>Gamma</role>
</root>
J'aimerais énumérer toutes les lignes qui jouent un rôle spécifique. Ce rôle passé par paramètre.
select
Roles
from
MyTable
where
Roles.value('(/root/role)[1]', 'varchar(max)') like 'StringToSearchFor'
Ces pages vous en apprendront davantage sur la façon d'interroger XML dans T-SQL:
Interrogation de champs XML à l'aide de t-sql
Aplatissement des données XML dans SQL Server
EDIT
Après avoir joué un peu plus, je me suis retrouvé avec cette requête étonnante qui utilise CROSS APPLY . Celui-ci va rechercher dans chaque rang (rôle) la valeur que vous mettez dans votre expression similaire ...
Étant donné cette structure de table:
create table MyTable (Roles XML)
insert into MyTable values
('<root>
<role>Alpha</role>
<role>Gamma</role>
<role>Beta</role>
</root>')
Nous pouvons l'interroger comme ceci:
select * from
(select
pref.value('(text())[1]', 'varchar(32)') as RoleName
from
MyTable CROSS APPLY
Roles.nodes('/root/role') AS Roles(pref)
) as Result
where RoleName like '%ga%'
Vous pouvez vérifier le code SQL Fiddle ici: http://sqlfiddle.com/#!3/ae0d5/1
declare @T table(Roles xml)
insert into @T values
('<root>
<role>Alpha</role>
<role>Beta</role>
<role>Gamma</role>
</root>')
declare @Role varchar(10)
set @Role = 'Beta'
select Roles
from @T
where Roles.exist('/root/role/text()[. = sql:variable("@Role")]') = 1
Si vous voulez que la requête fonctionne comme where col like '%Beta%'
, vous pouvez utiliser contains
declare @T table(Roles xml)
insert into @T values
('<root>
<role>Alpha</role>
<role>Beta</role>
<role>Gamma</role>
</root>')
declare @Role varchar(10)
set @Role = 'et'
select Roles
from @T
where Roles.exist('/root/role/text()[contains(., sql:variable("@Role"))]') = 1
si votre nom de champ est Roles et que le nom de table est Table1, vous pouvez utiliser ce qui suit pour effectuer une recherche.
DECLARE @Role varchar(50);
SELECT * FROM table1
WHERE Roles.exist ('/root/role = sql:variable("@Role")') = 1
Je suis venu avec un travail simple ci-dessous qui est facile à retenir aussi :-)
select * from
(select cast (xmlCol as varchar(max)) texty
from myTable (NOLOCK)
) a
where texty like '%MySearchText%'
Vous pouvez faire ce qui suit
declare @role varchar(100) = 'Alpha'
select * from xmltable where convert(varchar(max),xmlfield) like '%<role>'+@role+'</role>%'
Évidemment, c'est un peu un bidouillage et je ne le recommanderais pas pour des solutions formelles. Cependant, je trouve cette technique très utile lors de requêtes ad hoc sur des colonnes XML dans SQL Server Management Studio pour SQL Server 2012.
Astuce utile. Interroger une valeur dans la colonne SQL Server XML (XML avec un espace de noms)
par exemple.
Table [dbo].[Log_XML] contains columns Parametrs (xml),TimeEdit (datetime)
par exemple. XML dans les paramètres:
<ns0:Record xmlns:ns0="http://Integration">
<MATERIAL>10</MATERIAL>
<BATCH>A1</BATCH>
</ns0:Record>
par exemple. Requete:
select
Parametrs,TimeEdit
from
[dbo].[Log_XML]
where
Parametrs.value('(//*:Record/BATCH)[1]', 'varchar(max)') like '%A1%'
ORDER BY TimeEdit DESC
J'ai utilisé l'instruction ci-dessous pour récupérer les valeurs dans le XML dans la table SQL
with xmlnamespaces(default 'http://test.com/2008/06/23/HL.OnlineContract.ValueObjects')
select * from (
select
OnlineContractID,
DistributorID,
SponsorID,
[RequestXML].value(N'/OnlineContractDS[1]/Properties[1]/Name[1]', 'nvarchar(30)') as [Name]
,[RequestXML].value(N'/OnlineContractDS[1]/Properties[1]/Value[1]', 'nvarchar(30)') as [Value]
,[RequestXML].value(N'/OnlineContractDS[1]/Locale[1]', 'nvarchar(30)') as [Locale]
from [OnlineContract]) as olc
where olc.Name like '%EMAIL%' and olc.Value like '%EMAIL%' and olc.Locale='UK EN'