web-dev-qa-db-fra.com

Comment interroger une valeur dans la colonne SQL Server XML

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.

120
Bistro
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

186
Leniel Maccaferri
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
35
Mikael Eriksson

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
13
AaA

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%'
7
Sagar

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.

5
Craig B

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
1
romangorbenko.com

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'
1
ranjit