Sql-Server

VARBINARY 列上的全文索引:如何查找帶點的字元串

  • June 29, 2017

在 SQL Server 2012 SP3 CU8 伺服器實例上,我們將 PDF 文件插入到名為OBJECT_FILEcreated 的表中,如下所示:

CREATE TABLE [dbo].[OBJECT_FILE](
   [FILE_ID] [int] NOT NULL,
   [FILE_FIN] [int] NOT NULL,
   [OBJ_FILE_IDX_DOCTYPE] [varchar](3) NULL,
   [FILE_TYPE] [smallint] NOT NULL,
   [FILE_TXT] [varbinary](max) NULL,
   [FILE_TXT_SIZE] [int] NULL DEFAULT ((0)),
   CONSTRAINT [PK_DM_OBJECT_FILE] PRIMARY KEY CLUSTERED (
       [FILE_ID] ASC
   )
   WITH (
       PAD_INDEX = OFF, 
       STATISTICS_NORECOMPUTE = OFF, 
       IGNORE_DUP_KEY = OFF, 
       ALLOW_ROW_LOCKS = ON, 
       ALLOW_PAGE_LOCKS = ON
   ) ON [INDEXFG]
) ON [INDEXFG] TEXTIMAGE_ON [BLOBFG]

我們還創建了一個基於FILE_TXT列的全文索引,它是一個 VARBINARY(MAX),創建如下:

CREATE FULLTEXT INDEX 
ON OBJECT_FILE (
   FILE_TXT TYPE COLUMN OBJ_FILE_IDX_DOCTYPE
) 
KEY INDEX PK_DM_OBJECT_FILE 
WITH STOPLIST=OFF;

在那個表中,我們願意插入舊文件的內容。在這些內容中,我們將找到一個插入過去的唯一標識符,該標識符遵循命名約定:

CORP-MMM-<three_digits_0_to_9>.<three_digits_0_to_9>

當我嘗試使用 CONTAINS 內置函式對我知道它存在的特定標識符進行查找時,它不會給我任何結果。我使用以下 WHERE 子句:

WHERE CONTAINS(FILE_TXT,'CORP-MMM-456.245')

儘管使用以下 WHERE 子句的查找為我提供了多個結果:

WHERE CONTAINS(FILE_TXT,'CORP-MMM-456.*')

並且可以通過以下方式找到相關記錄LIKE

WHERE FILE_TXT LIKE '%CORP-MMM-456.245%' 

我的問題是:

為什麼我不能獲得關於我的 WHERE 子句的特定記錄,我怎樣才能讓它發揮作用?

解決方案包括將全文索引從英語更改為中性語言。

這可以使用sys.dm_fts_parserSQL Server 的以下內置函式來解釋。

select * from sys.dm_fts_parser( '" dsolkjfdskljfsd dfsd-MMM-236.127 dojfdslfkjds"', 1033, -- English NULL, 0 ) ;

導致刪除“。” 關鍵字中的字元:

使用語言 = 英語進行全文字元串解析

而以下程式碼使此字元可用於查找: select * from sys.dm_fts_parser( '" dsolkjfdskljfsd dfsd-MMM-236.127 dojfdslfkjds"', 0, -- Neutral NULL, 0 ) ; 結果:

使用 Language = Neutral 解析全文字元串

我們刪除了現有索引並使用LANGUAGE 0選項創建它,這解決了我們的問題。

抱歉,這可能不是答案,但我不能對此發表評論。根據 OP @Jefferson 的評論(作為對我評論的回答),我無法重現該行為。我可以使用與該值完全匹配的 where 子句獲取記錄。

我用下面的程式碼測試了這個(從這裡複製和修改)

CREATE TABLE Department 
  (DepartmentID INT IDENTITY CONSTRAINT DepartmentPK PRIMARY KEY, 
   NAME NVARCHAR(50),
   File_txt NVARCHAR(50));
GO
INSERT INTO Department (NAME, File_txt) VALUES ('OP1', 'CORP-MMM-456.245');
INSERT INTO Department (NAME, File_txt) VALUES ('OP2', 'CORP-MMM-456.246');
INSERT INTO Department (NAME, File_txt) VALUES ('OP3', 'CORP-MMM-456.247');
INSERT INTO Department (NAME, File_txt) VALUES ('OP4', 'CORP-MMM-456.245.246');

Go
CREATE FULLTEXT CATALOG ComplexFTS AS DEFAULT;
GO
CREATE FULLTEXT INDEX ON Department(File_txt LANGUAGE 1033 /* 0 = Neutral, 1033 = American English  */)  
KEY INDEX DepartmentPK WITH (STOPLIST = OFF); /* Or use (stoplist = Off) for no stoplist */
GO
WAITFOR DELAY '00:00:05';
GO
SELECT * FROM Department WHERE CONTAINS (File_txt,'"CORP-MMM-456.*"');
SELECT * FROM Department  WHERE CONTAINS(File_txt,'CORP-MMM-456.245')
GO

這就是我得到的結果集。

在此處輸入圖像描述

清理程式碼。

DROP FULLTEXT INDEX ON Department;
GO
DROP FULLTEXT CATALOG ComplexFTS;
GO
DROP TABLE Department;
GO

引用自:https://dba.stackexchange.com/questions/177342