T-SQL LIKE 謂詞無法與 XML 轉換的 varchar 中的空格匹配
XML
最近,我嘗試通過將數據轉換為特定模式來搜尋特定模式,varchar(max)
儘管我知道這不是最佳實踐並且發現它沒有按預期工作:-設置
declare @container table( [Response] xml not null ); declare @xml xml = '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://abc.com/xsd" xmlns:ns="http://abc.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <soapenv:Header> <ns:MessageHeader> <xsd:ID>ABC</xsd:ID> <xsd:Date>2018-12-31T23:59:59</xsd:Date> </ns:MessageHeader> </soapenv:Header> <soapenv:Body> <ns:MessageResponse> <ns:return> <xsd:ResponseList xsi:nil="true" /> </ns:return> </ns:MessageResponse> </soapenv:Body> </soapenv:Envelope>'; insert into @container values (@xml);
此查詢有效
select * from @container where cast(Response as varchar(max)) like '%<xsd:ResponseList xsi:nil="true"%';
注意萬用字元在 XML 節點之前**結束 3 個字元(即)
' />'
但這不是
select * from @container where cast(Response as varchar(max)) like '%<xsd:ResponseList xsi:nil="true" %' -- with space or cast(Response as varchar(max)) like '%<xsd:ResponseList xsi:nil="true" />%' -- whole XML node;
我懷疑這可能是由於轉義字元並嘗試了其他一些替代方法但無濟於事,如果有人能對此有所了解,請不勝感激。
編輯(已回答)
以下查詢將根據 Browstone 先生的見解起作用:-
select * from @container where cast(Response as varchar(max)) like '%<xsd:ResponseList xsi:nil="true"/>%';
這是我的關注問題@CodeReview 和 XQuery 表達式:-
這是設計使然。
當您使用 XML 數據類型儲存文件時,它會被壓縮並組織成 Sql Server 可以有效執行操作的結構。它執行此操作的步驟之一是生成InfoSet。當它這樣做時,它會刪除它確定不必要的任何內容,在您的範例中為空格:
InfoSet 內容可能不是文本 XML 的相同副本,因為不保留以下資訊:無關緊要的空格、屬性順序、名稱空間前綴和 XML 聲明。
當您選擇欄位的全部內容時(例如,當您將其轉換為它時,
NVARCHAR(MAX)
會在返回之前重新建構 XML 文件。此文件可能與您插入的文件的副本不同。例如,如果您使用了 self -關閉元素,Sql Server 可能會返回打開和關閉元素。該文件還繼續說:
範例:保留 XML 數據的精確副本
舉例來說,假設政府法規要求您保留 XML 文件的準確文本副本。例如,這些可能包括簽署的文件、法律文件或股票交易訂單。您可能希望將文件儲存在
$$ n $$varchar(max) 列。
因此,如果您想儲存文件的準確副本,那麼
NVARCHAR(MAX)
orVARCHAR(MAX)
是最佳選擇。然後,您可以將其轉換為 XML 以供以後查詢(儘管這可能代價高昂)。有關詳細資訊,請參閱有關XML 數據類型和列 (SQL Server)的文件以及定義 XML 數據的序列化,其中概述了 Sql Server 在將 XML 轉換為字元串類型時應用的規則。