मैं SQL सर्वर XML स्तंभ में किसी मान को कैसे क्वेरी कर सकता हूं


127

मेरे पास RolesSQL सर्वर डेटाबेस में XML कॉलम (कहा जाता है ) में संग्रहीत XML है।

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

मैं उन सभी पंक्तियों को सूचीबद्ध करना चाहूंगा जिनमें उनकी एक विशिष्ट भूमिका है। यह भूमिका पैरामीटर द्वारा पारित की गई है।

जवाबों:


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

ये पृष्ठ आपको टी-एसक्यूएल में एक्सएमएल को क्वेरी करने के तरीके के बारे में अधिक दिखाएंगे:

T-sql का उपयोग करके XML फ़ील्ड्स को छोड़ना

SQL सर्वर में समतल XML डेटा

संपादित करें

इसके साथ थोड़ा और खेलने के बाद, मैं इस अद्भुत क्वेरी के साथ समाप्त हुआ जो CROSS APPLY का उपयोग करता है । यह आपकी अभिव्यक्ति के लिए आपके द्वारा डाले गए मूल्य के लिए हर पंक्ति (भूमिका) की खोज करेगा ...

इस तालिका संरचना को देखते हुए:

create table MyTable (Roles XML)

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

हम इसे इस तरह से क्वेरी कर सकते हैं:

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

आप यहां SQL Fiddle को देख सकते हैं: http://sqlfiddle.com/# -18 / dc4d2/1 /0


5
यह मेरे सभी प्रश्न का उत्तर देता [1]है, आपके उत्तर में क्या करता है?
बिस्ट्रो

1
महान जवाब, मैं इस एक के लिए वोट करता हूं, लेकिन स्ट्रिंग को मुझे लगता है कि होना चाहिए
AAA

7
@ बिस्त्रो के बारे [1]में पूछना वास्तव में एक अच्छा सवाल था। इसका मतलब है कि आप XML से पहली भूमिका मान लेते हैं और इसका मतलब है कि यह केवल Alphaआपके नमूना xml में खोजने के लिए काम करेगा । यदि आप खोज करेंगे तो यह पंक्ति नहीं मिलेगी Beta
मिकेल एरिकसन

1
मेरे मामले में, मुझे विशिष्ट विशेषता मान के साथ नोड्स को क्वेरी करना था। यह जवाब मेरे समाधान का नेतृत्व था। मुझे सिर्फ विशेषता मूल्य के आसपास दोहरे उद्धरण चिह्नों को लगाना था।
जॉन एन

यदि XML में एक नाम स्थान है, तो हम इसे कैसे क्वेरी करते हैं?
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

यदि आप क्वेरी को काम करना चाहते हैं जैसा कि where col like '%Beta%'आप उपयोग कर सकते हैं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

13

यदि आपके क्षेत्र का नाम रोल्स है और तालिका का नाम टेबल 1 है तो आप खोज के लिए उपयोग कर सकते हैं

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

यह अच्छा है, यहाँ किसी भी तरह से खोज का उपयोग किया जा रहा है like? forexample /root/role like ....
बिस्ट्रो

2
का उपयोग .value('(/root/role)[1]', 'varchar(max)') like '%yourtext%'करने के बजाय existsके रूप में Leniel समझाया
एएए

4
क्या आपने यह कोशिश की है? यह सब कुछ पाता है, भले ही आप जो कुछ भी डालें @Role
मिकेल एरिकसन

6

मैं नीचे एक साधारण काम के साथ आया था जिसे याद रखना आसान है :-)

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

1
हम स्ट्रिंग हेरफेर के माध्यम से खोज करने वाले नहीं हैं, क्योंकि यह बहुत धीमी खोजों के परिणामस्वरूप होगा
मैल्कम सल्वाडोर

5

आप निम्नलिखित कर सकते हैं

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

जाहिर है यह एक हैक का एक सा है और मैं इसे किसी भी औपचारिक समाधान के लिए अनुशंसित नहीं करूंगा। हालाँकि मुझे यह तकनीक बहुत उपयोगी लगती है जब SQL Server 2012 के लिए SQL Server Management Studio में XML कॉलमों पर एडहॉक क्वेश्चन करते हैं।


2

उपयोगी टिप। SQL सर्वर XML स्तंभ में XML मान (नाम स्थान के साथ XML)

जैसे

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

उदाहरण के लिए पैरामीटर में XML:

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

उदाहरण के लिए प्रश्न:

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

1

मैंने Sql तालिका में XML में मान पुनः प्राप्त करने के लिए नीचे दिए गए कथन का उपयोग किया

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'

यदि XML में Namespace की परिभाषा नहीं है तो क्या होगा?
मुफ्लिक्स

0

आप पूरे टैग या केवल विशिष्ट मान को क्वेरी कर सकते हैं। यहां मैं 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
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.