4

以下是我的sql查詢的簡化版本,它使用CONTAINSTABLE進行全文搜索。SQL Server - 使用空關鍵字進行自由文本搜索

DECLARE @pSearchFor AS NVARCHAR(100); 
SET @pSearchFor = 'SomeKeyword'; 

SELECT MS.[ModuleScreenID] AS ScreenID 
    ,MS.[ModuleScreenCode] AS ScreenCode 
    ,M.[Description] AS ModuleDescription 
    ,M.[ModuleCode] AS ModuleCode   
    ,FT.[Rank] 
FROM ModuleScreen MS 
    JOIN Module M ON MS.ModuleID = M.ModuleID 
    JOIN CONTAINSTABLE(ModuleScreen, *, @pSearchFor) FT ON MS.ModuleScreenID = FT.[KEY] 

我想通過空或空值,這樣所有記錄都通過全文搜索返回 @pSearchFor參數。但是當我傳遞空值或空值時,我得到一個「空或全空全文謂詞」錯誤。 Google搜索後,我發現CONTAINSTABLE無法爲關鍵字提供空白參數。我在SO中也看到了這個question,但它沒有幫助我。

我可以使用CONTAINSTABLE進行條件連接(僅當爲@pSearchFor參數指定了值時)?我不知道如何實現這一點。將不勝感激任何指針。

回答

0

當您搜索空值或空值時,您期望得到什麼?你希望查詢什麼都不返回,或者你期望它返回其他的東西。

如果你希望它返回任何結果那麼你最好做這樣的事情的:

DECLARE @pSearchFor AS NVARCHAR(100); 
SET @pSearchFor = 'SomeKeyword'; 

IF @pSearchFor IS NOT NULL AND @pSearchFor <> '' 
BEGIN 
    SELECT MS.[ModuleScreenID] AS ScreenID 
     ,MS.[ModuleScreenCode] AS ScreenCode 
     ,M.[Description] AS ModuleDescription 
     ,M.[ModuleCode] AS ModuleCode   
     ,FT.[Rank] 
    FROM ModuleScreen MS 
     JOIN Module M ON MS.ModuleID = M.ModuleID 
     JOIN CONTAINSTABLE(ModuleScreen, *, @pSearchFor) FT ON MS.ModuleScreenID = FT.[KEY] 
END 
ELSE 
BEGIN 
    SELECT MS.[ModuleScreenID] AS ScreenID 
     ,MS.[ModuleScreenCode] AS ScreenCode 
     ,M.[Description] AS ModuleDescription 
     ,M.[ModuleCode] AS ModuleCode   
     ,FT.[Rank] 
    FROM ModuleScreen MS 
     JOIN Module M ON MS.ModuleID = M.ModuleID 
END 

編輯:固定到現在返回的所有記錄時,提供null或空字符串。

如果你有超過2包含表的查詢與不同的搜索字符串,那麼我建議您將使用動態SQL查詢,因爲它會更容易維護比幾乎相同的查詢

的2^N鏈

編輯:已經看了一個辦法做到這一點,而無需使用多個副本通過使用臨時表是這樣的:

DECLARE @pSearchFor AS NVARCHAR(100); 
SET @pSearchFor = 'SomeKeyword'; 

SELECT * INTO #temp FROM CONTAINSTABLE(ModuleScreen, *, @pSearchFor) 

SELECT MS.[ModuleScreenID] AS ScreenID 
    ,MS.[ModuleScreenCode] AS ScreenCode 
    ,M.[Description] AS ModuleDescription 
    ,M.[ModuleCode] AS ModuleCode   
    ,FT.[Rank] 
FROM Module M 
    JOIN ModuleScreen MS ON MS.ModuleID = M.ModuleID AND (
     (1 = CASE WHEN ISNULL(@pSearchFor, '') = '' THEN 1 ELSE 0 END 
     OR CONTAINS(MS.*, @pSearchFor) 
    LEFT OUTER JOIN #temp FT ON MS.ModuleScreenID = FT.[Key] 

這應該給你想要的東西,而不必重複的事情,但是你可能希望限制結果被饋入#temp表格的更多,因爲對於更大的表格來說它會變慢。

+0

我希望關鍵字爲空或空時返回所有記錄。我在原來的問題中也提到過這個問題。 – muruge 2011-05-03 23:21:15

+0

查看更新的答案,希望這可以幫助你。 – Seph 2011-05-04 03:47:42

+0

感謝您的建議。我想到了這個答案,但我不想在編輯的答案中提及兩次使用相同的查詢。此外,我必須在存儲過程中使用此查詢,並且不能使用動態SQL。有沒有辦法**有條件地加入CONTAINSTABLE **? – muruge 2011-05-04 14:31:28

3
DECLARE @pSearchFor AS NVARCHAR(100); 

SET @pSearchFor = 'SomeKeyword'; 
--if @pSearch comes as parameter then -- 
set @pSearch = ISNULL(@pSearch,'*') 

SELECT MS.[ModuleScreenID] AS ScreenID 
    ,MS.[ModuleScreenCode] AS ScreenCode 
    ,M.[Description] AS ModuleDescription 
    ,M.[ModuleCode] AS ModuleCode   
    ,FT.[Rank] 
FROM ModuleScreen MS 
    JOIN Module M ON MS.ModuleID = M.ModuleID 
    JOIN CONTAINSTABLE(ModuleScreen, *, @pSearchFor) FT ON MS.ModuleScreenID = FT.[KEY] 
where @pSearchFor = '*' OR FT.[KEY] is not null 

我只是解決了完全相同的問題,並幫助你出去的想法。

+0

搖滾,這爲我工作。謝謝。 – Jeremy 2013-04-25 16:02:13

-1

我也有完全相同的問題,並通過向所有記錄的搜索索引列添加/附加虛擬關鍵字'fts'來解決此問題。

if(nullif(@pSearchFor,'') is null) 
begin 
    set @pSearchFor= 'fts';     
end 
相關問題