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 
相关问题