Câu trả lời:
select
Roles
from
MyTable
where
Roles.value('(/root/role)[1]', 'varchar(max)') like 'StringToSearchFor'
Các trang này sẽ cho bạn biết thêm về cách truy vấn XML trong T-SQL:
Truy vấn các trường XML bằng cách sử dụng t-sql
Làm phẳng dữ liệu XML trong SQL Server
BIÊN TẬP
Sau khi chơi với nó thêm một chút nữa, tôi đã kết thúc với truy vấn tuyệt vời này sử dụng CROSS ỨNG DỤNG . Cái này sẽ tìm kiếm mọi hàng (vai trò) cho giá trị bạn đặt trong biểu thức thích của bạn ...
Cho cấu trúc bảng này:
create table MyTable (Roles XML)
insert into MyTable values
('<root>
<role>Alpha</role>
<role>Gamma</role>
<role>Beta</role>
</root>')
Chúng ta có thể truy vấn nó như thế này:
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%'
Bạn có thể kiểm tra SQL Fiddle tại đây: http://sqlfiddle.com/#!18/dc4d2/1/0
[1]
là một câu hỏi thực sự tốt. Điều đó có nghĩa là bạn chọn giá trị vai trò đầu tiên từ XML và điều đó có nghĩa là điều này sẽ chỉ hoạt động để tìm Alpha
trong xml mẫu của bạn. Nó sẽ không tìm thấy hàng nếu bạn tìm kiếm Beta
.
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
Nếu bạn muốn truy vấn hoạt động như where col like '%Beta%'
bạn có thể sử dụngcontains
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
nếu tên trường của bạn là Vai trò và tên bảng là bảng1, bạn có thể sử dụng theo sau để tìm kiếm
DECLARE @Role varchar(50);
SELECT * FROM table1
WHERE Roles.exist ('/root/role = sql:variable("@Role")') = 1
like
? forexample /root/role like ....
.value('(/root/role)[1]', 'varchar(max)') like '%yourtext%'
thay vì exists
như Leniel đã giải thích
@Role
.
Tôi đã nghĩ ra một công việc đơn giản xung quanh bên dưới cũng dễ nhớ :-)
select * from
(select cast (xmlCol as varchar(max)) texty
from myTable (NOLOCK)
) a
where texty like '%MySearchText%'
Bạn có thể làm như sau
declare @role varchar(100) = 'Alpha'
select * from xmltable where convert(varchar(max),xmlfield) like '%<role>'+@role+'</role>%'
Rõ ràng đây là một chút hack và tôi sẽ không đề xuất nó cho bất kỳ giải pháp chính thức nào. Tuy nhiên, tôi thấy kỹ thuật này rất hữu ích khi thực hiện các truy vấn adhoc trên các cột XML trong SQL Server Management Studio cho SQL Server 2012.
Lời khuyên hữu ích. Truy vấn một giá trị trong cột XML của SQL Server (XML có không gian tên)
ví dụ
Table [dbo].[Log_XML] contains columns Parametrs (xml),TimeEdit (datetime)
ví dụ: XML trong Parametrs:
<ns0:Record xmlns:ns0="http://Integration">
<MATERIAL>10</MATERIAL>
<BATCH>A1</BATCH>
</ns0:Record>
ví dụ: Truy vấn:
select
Parametrs,TimeEdit
from
[dbo].[Log_XML]
where
Parametrs.value('(//*:Record/BATCH)[1]', 'varchar(max)') like '%A1%'
ORDER BY TimeEdit DESC
Tôi đã sử dụng câu lệnh dưới đây để lấy các giá trị trong XML trong bảng 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'
Bạn có thể truy vấn toàn bộ thẻ, hoặc chỉ giá trị cụ thể. Ở đây tôi sử dụng ký tự đại diện cho các không gian tên 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
[1]
làm gì trong câu trả lời của bạn?