2011-10-10 29 views
5

işareti (&) ile sorun var SQL Server tam metin arama işareti (&)

işaretini (&) bulunan kelimeler (veya cümle) nasıl aranır. veritabanında Örneğin

, şunlardır:

1: "Johnson & Johnson" 
2: "AT&T" 
3: "Sample & Sample" 

nasıl bireysel kayıtlar aramak için tam metin arama sorgusunu yazmalıyım?

SELECT * from Companies c WHERE CONTAINS(c.CompanyName, '"AT&T"') 

O karakteri (&) mantıksal VE işlemi sorumludur biliyorum. Ama tam metin arama kullanımı ile metin aramak için onu nasıl kodlayacağımı bilmiyorum.

Herhangi bir fikrin var mı?

cevap

5

Kısa versiyon: yapamazsınız (veya en azından yapabilirsiniz, ama sen beklenenden daha fazla sonuçlar alabilirsiniz)

Uzun versiyon: karakter '&' bir "kelimesi kesici" olarak ele alınır Yani, SQL Server bir '&' ile karşılaştığında, bunu yeni bir "kelime" nin başlangıcı (yani simge) olarak ele alır. "AT&T" ayrıştırılırken hangi SQL Server görürse iki simge, "AT" ve "T".

Kendinizi sys.dm_fts_parser kullanmak için bu kontrol edebilirsiniz:

SELECT * FROM sys.dm_fts_parser('AT&T', 1033, 0, 0) 

keyword  group_id phrase_id occurrence special_term display_term expansion_type source_term 
----------- ----------- ----------- ----------- ------------- ------------- -------------- ----------- 
0x00610074 1   0   1   Noise Word at   0    AT 
0x0074  2   0   1   Noise Word t    0    T 

Bu "AT&T" arayışı hemen hemen tam olarak sadece "AT T" ararken aynı olduğu anlamına gelir.

Bu, tasarım gereğince, bu davranışı değiştirmenin tek yolunun kendi word breaker'u yüklemesini gerektirdiğine inanıyorum, ancak bunu yapmasını öneriyorum.

2

Kabul edilen yanıt tamamen doğru değil. Arama terimini çift tırnak içine almak, kelimelerin gruplamasını "ifade" eşleşmesini sağlar. Bu durumda, (&) ve (&), bilinen bir sözcük oluşturmayan bir veya daha fazla harf tarafından çevrelenmiş gibi bir tam karakter olarak ele alınabilir. Sadece "AT&T" örneğe bakarak, gördüğümüz:

DECLARE @Term NVARCHAR(100); 
SET @Term = N'"AT&T"'; 

SELECT * FROM sys.dm_fts_parser(@Term, 1033, 0, 0); 
SELECT * FROM sys.dm_fts_parser(@Term, 1033, 0, 1); 
SELECT * FROM sys.dm_fts_parser(@Term, 1033, NULL, 0); 
SELECT * FROM sys.dm_fts_parser(@Term, 1033, NULL, 1); 
GO 

İade:

keyword    group phrase occurrence special  display expansion source 
        id  id     term   term  type  term 
0x0061007400260074 1  0  1   Exact Match at&t  0   AT&T 

Gördüğünüz gibi, ve işareti o (çift tırnak içine alınır sürece, hiçbir sorun teşkil ") zaten yapıyorsun, hoo hoo!

DECLARE @Term NVARCHAR(100); 
SET @Term = N'"Johnson & Johnson"'; 

SELECT * FROM sys.dm_fts_parser(@Term, 1033, 0, 0); 
SELECT * FROM sys.dm_fts_parser(@Term, 1033, 0, 1); 
SELECT * FROM sys.dm_fts_parser(@Term, 1033, NULL, 0); 
SELECT * FROM sys.dm_fts_parser(@Term, 1033, NULL, 1); 
GO 

İade: "Johnson & Johnson" örneğin temiz bir şekilde çalışmaz Ancak

,

keyword       group phrase occurrence special  display expansion source 
           id  id     term   term  type  term 
0x006A006F0068006E0073006F006E 1  0  1   Exact Match johnson 0   Johnson & Johnson 
0x006A006F0068006E0073006F006E 1  0  2   Exact Match johnson 0   Johnson & Johnson 
da değil, hangi Johnson Johnson bir aradığı terime görünüyor

teknik olarak doğru.

DECLARE @Term NVARCHAR(100); 
SET @Term = N'"Johnson _ Johnson"'; 

SELECT * FROM sys.dm_fts_parser(@Term, 1033, 0, 0); 
SELECT * FROM sys.dm_fts_parser(@Term, 1033, 0, 1); 
SELECT * FROM sys.dm_fts_parser(@Term, 1033, NULL, 0); 
SELECT * FROM sys.dm_fts_parser(@Term, 1033, NULL, 1); 
GO 

İade:

Yani, çift tırnak içinde kapsayan ek olarak, aynı zamanda farklı şekilde ele alınır bir alt çizgi (_) olmak işareti dönüştürebilirsiniz

keyword       group phrase occurrence special  display expansion source 
           id  id     term   term  type  term 
0x006A006F0068006E0073006F006E 1  0  1   Exact Match johnson 0   Johnson _ Johnson 
0x005F       1  0  2   Exact Match _  0   Johnson _ Johnson 
0x006A006F0068006E0073006F006E 1  0  3   Exact Match johnson 0   Johnson _ Johnson 

VE Bu bir karakter çeviri yapmak orijinal "AT&T" arama olumsuz etkilemiyor gibi görünüyor:

DECLARE @Term NVARCHAR(100); 
SET @Term = N'"AT_T"'; 

SELECT * FROM sys.dm_fts_parser(@Term, 1033, 0, 0); 
SELECT * FROM sys.dm_fts_parser(@Term, 1033, 0, 1); 
SELECT * FROM sys.dm_fts_parser(@Term, 1033, NULL, 0); 
SELECT * FROM sys.dm_fts_parser(@Term, 1033, NULL, 1); 
İlgili konular