SQL Server XML Veri Tipinde LIKE deyimi kullanın


89

Bir varchar alanınız varsa kolayca yapabilirsiniz SELECT * FROM TABLE WHERE ColumnA LIKE '%Test%' bu sütunun belirli bir dizeyi içerip içermediğini görebilirsiniz.

Bunu XML Türü için nasıl yaparsınız?

Yalnızca 'Metin' düğümü olan satırları döndüren aşağıdakilere sahibim, ancak bu düğüm içinde aramam gerekiyor

select * from WebPageContent where data.exist('/PageContent/Text') = 1

Yanıtlar:


70

Bunu oldukça kolay bir şekilde yapabilmelisiniz:

SELECT * 
FROM WebPageContent 
WHERE data.value('(/PageContent/Text)[1]', 'varchar(100)') LIKE 'XYZ%'

.valueYöntem, gerçek değeri verir ve sonra bir gibi bir ifade kontrol bir VARCHAR () olarak döndürülecek bu tanımlayabilir.

Unutmayın, bu çok hızlı olmayacak. Dolayısıyla, XML'nizde çokça incelemeniz gereken belirli alanlar varsa, şunları yapabilirsiniz:

  • XML'yi alan ve aradığınız değeri bir VARCHAR () olarak döndüren depolanmış bir işlev oluşturun
  • Tablonuzda bu işlevi çağıran yeni bir hesaplanan alan tanımlayın ve onu DEVAMLI bir sütun yapın

Bununla, temelde XML'in belirli bir bölümünü hesaplanan bir alana "çıkarırsınız", onu kalıcı hale getirirsiniz ve sonra üzerinde çok verimli bir şekilde arama yapabilirsiniz (heck: bu alanı bile INDEX yapabilirsiniz!).

Marc


1
Temelde bir arama özelliğini uyguluyorum, bu nedenle XML sütununu yalnızca 'Metin' düğümlerinde aramak ve ardından aramanın bir eşleşme bulduğunu belirtmek için bir alt dize döndürmek istiyorum. Örneğin, tüm xml sütununu döndürmek yerine 'merhaba' araması yapmak yerine, 'adam merhaba dedi ve taşıdı ...' gibi bir alt dize döndürürdüm
Jon

1
Beni 5 saniye döv. Diğer bir olasılık, verileriniz uygunsa, serbest metin aramayı kullanmayı düşünmektir ...
RickNZ

10
dosyanın tamamını aramak için: WHERE xmlField.value ('.', 'varchar (max)') GİBİ '% FOO%'
jhilden

NULL geri gelirse sinir bozucu Xml ad alanlarına dikkat edin
Simon_Weaver

89

Yine başka bir seçenek de XML'i nvarchar olarak çevirmek ve ardından verilen dizeyi XML sanki bir nvarchar alanıymış gibi aramaktır.

SELECT * 
FROM Table
WHERE CAST(Column as nvarchar(max)) LIKE '%TEST%'

Temiz olması, hatırlaması kolay, karıştırması zor ve where cümlesinin bir parçası olarak kullanılabileceği için bu çözümü seviyorum.

DÜZENLEME: Cliff'in bahsettiği gibi şunları kullanabilirsiniz:

... varchar'a dönüştürülmeyen karakterler varsa nvarchar


3
Bunun üzerine aynen veya varchar'a dönüştürülmeyen karakterler varsa nvarchar SELECT * FROM Table WHERE WHERE (Column as nvarchar (max)) GİBİ '% TEST%'
Cliff Coulter,

[Err] 42000 - [SQL Sunucusu] XML'den hedef harmanlamaya bir veya daha fazla karakterin dönüştürülmesi imkansız
digz6666

[Err] 22018 - [SQL Server] xml veri türünden metne açık dönüşüme izin verilmiyor.
digz6666

Yanlış bir şey yapıyormuşsunuz gibi görünüyor @ digz6666
Squazz

1
@Squazz Bu yanıta en son dün oy verdiniz. Bu yanıt düzenlenmediği sürece oyunuz artık kilitlendi. :)
digz6666

10

Diğer bir seçenek, XML'i bir dizeye dönüştürerek ve ardından LIKE kullanarak bir dize olarak aramaktır. Ancak, hesaplanan bir sütun bir WHERE yan tümcesinin parçası olamayacağından, onu aşağıdaki gibi başka bir SELECT ile sarmalamanız gerekir:

SELECT * FROM
    (SELECT *, CONVERT(varchar(MAX), [COLUMNA]) as [XMLDataString] FROM TABLE) x
WHERE [XMLDataString] like '%Test%'

Bunun, sahip olabileceğiniz herhangi bir seçici xml dizinini atlayabileceğini ve performansı etkileyebileceğini unutmayın.
Rudy Hinojosa

0

Marc_s cevabına göre kullanacağım şey bu:

SELECT 
SUBSTRING(DATA.value('(/PAGECONTENT/TEXT)[1]', 'VARCHAR(100)'),PATINDEX('%NORTH%',DATA.value('(/PAGECONTENT/TEXT)[1]', 'VARCHAR(100)')) - 20,999)

FROM WEBPAGECONTENT 
WHERE COALESCE(PATINDEX('%NORTH%',DATA.value('(/PAGECONTENT/TEXT)[1]', 'VARCHAR(100)')),0) > 0

Arama kriterlerinin bulunduğu aramada bir alt dize döndür


Enjeksiyonu bir şekilde önlemek için parametrelere ihtiyacım var mı?
Jon

2
FARKINDA OLUN: Bu XML fonksiyonu harfe duyarlı ARE - DATA.VALUE olmaz çalışır! .Value (...)
marc_s
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.