Bagaimana saya bisa meminta nilai dalam kolom SQL Server XML


127

Saya telah mengikuti XML yang disimpan dalam kolom XML (disebut Roles) dalam database SQL Server.

<root>
   <role>Alpha</role>
   <role>Beta</role>
   <role>Gamma</role>
</root>

Saya ingin mendaftar semua baris yang memiliki peran khusus di dalamnya. Peran ini dilewati oleh parameter.

Jawaban:


198
select
  Roles
from
  MyTable
where
  Roles.value('(/root/role)[1]', 'varchar(max)') like 'StringToSearchFor'

Halaman-halaman ini akan menunjukkan kepada Anda lebih lanjut tentang cara query XML di T-SQL:

Permintaan kolom XML menggunakan t-sql

Meratakan Data XML dalam SQL Server

EDIT

Setelah bermain dengannya sedikit lebih banyak, saya berakhir dengan permintaan yang luar biasa ini yang menggunakan CROSS APPLY . Yang ini akan mencari setiap baris (peran) untuk nilai yang Anda masukkan dalam ekspresi seperti Anda ...

Diberikan struktur tabel ini:

create table MyTable (Roles XML)

insert into MyTable values
('<root>
   <role>Alpha</role>
   <role>Gamma</role>
   <role>Beta</role>
</root>')

Kami dapat menanyakannya seperti ini:

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

Anda dapat memeriksa SQL Fiddle di sini: http://sqlfiddle.com/#!18/dc4d2/1/0


5
Itu menjawab semua pertanyaan saya, apa yang [1]dilakukan dalam jawaban Anda?
Bistro

1
Jawaban yang bagus, saya memilih yang ini, tapi saya kira string harus varchar
AaA

7
@Bistro Bertanya tentang [1]pertanyaan yang sangat bagus. Ini berarti bahwa Anda memilih nilai peran pertama dari XML dan itu berarti bahwa ini hanya akan berfungsi untuk menemukan Alphadi xml sampel Anda. Tidak akan menemukan baris jika Anda mencari Beta.
Mikael Eriksson

1
Dalam kasus saya, saya harus meminta node dengan nilai atribut tertentu. Jawaban ini adalah petunjuk untuk solusi saya. Saya hanya perlu memberikan tanda kutip ganda di sekitar nilai atribut.
John N

Jika XML memiliki namespace, bagaimana kami menanyakannya?
FMFF

36
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

Jika Anda ingin kueri berfungsi seperti where col like '%Beta%'yang dapat Anda gunakancontains

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

13

jika nama bidang Anda adalah Peran dan nama tabel adalah table1 Anda dapat menggunakan berikut untuk mencari

DECLARE @Role varchar(50);
SELECT * FROM table1
WHERE Roles.exist ('/root/role = sql:variable("@Role")') = 1

ini bagus, apakah di sini ada cara untuk mencari menggunakan like? forexample /root/role like ....
Bistro

2
gunakan .value('(/root/role)[1]', 'varchar(max)') like '%yourtext%'alih-alih existsseperti yang dijelaskan Leniel
AaA

4
Sudahkah Anda mencoba ini? Ia menemukan segalanya, terlepas dari apa yang Anda masukkan @Role.
Mikael Eriksson

6

Saya datang dengan pekerjaan sederhana di bawah ini yang juga mudah diingat :-)

select * from  
(select cast (xmlCol as varchar(max)) texty
 from myTable (NOLOCK) 
) a 
where texty like '%MySearchText%'

1
Kami tidak seharusnya mencari melalui manipulasi string, karena itu akan menghasilkan pencarian yang terlalu lambat
Malcolm Salvador

5

Anda bisa melakukan hal berikut

declare @role varchar(100) = 'Alpha'
select * from xmltable where convert(varchar(max),xmlfield) like '%<role>'+@role+'</role>%'

Jelas ini adalah sedikit peretasan dan saya tidak akan merekomendasikannya untuk solusi formal apa pun. Namun saya menemukan teknik ini sangat berguna ketika melakukan permintaan adhoc pada kolom XML di SQL Server Management Studio untuk SQL Server 2012.


2

Tip yang bermanfaat. Permintaan nilai dalam kolom SQL Server XML (XML dengan namespace)

misalnya

Table [dbo].[Log_XML] contains columns Parametrs (xml),TimeEdit (datetime)

misalnya XML dalam Parameter:

<ns0:Record xmlns:ns0="http://Integration"> 
<MATERIAL>10</MATERIAL> 
<BATCH>A1</BATCH> 
</ns0:Record>

mis. Permintaan:

select
 Parametrs,TimeEdit
from
 [dbo].[Log_XML]
where
 Parametrs.value('(//*:Record/BATCH)[1]', 'varchar(max)') like '%A1%'
 ORDER BY TimeEdit DESC

1

Saya menggunakan pernyataan di bawah ini untuk mengambil nilai-nilai dalam XML pada tabel 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'

Bagaimana jika XML tidak mengandung definisi Namespace?
Muflix

0

Anda dapat meminta seluruh tag, atau hanya nilai spesifik. Di sini saya menggunakan wildcard untuk ruang nama xml.

declare @myDoc xml
set @myDoc = 
'<Root xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://stackoverflow.com">
    <Child>my value</Child>
 </Root>'

select @myDoc.query('/*:Root/*:Child') -- whole tag
select @myDoc.value('(/*:Root/*:Child)[1]', 'varchar(255)') -- only value
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.