SQL Server - 使用空关键字进行自由文本搜索

mur*_*uge 5 sql-server full-text-search containstable sql-server-2008

下面是我的SQL查询的简化版本,它使用CONTAINSTABLE进行全文搜索.

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]
Run Code Online (Sandbox Code Playgroud)

我想为@pSearchFor参数传递空值或空值,以便通过全文搜索返回所有记录.但是当我传递空值或空值时,我得到一个"空或空全文谓词"错误.谷歌搜索后,我发现CONTAINSTABLE不能为关键字取一个空参数.我也在SO中看过这个问题,但它对我没有帮助.

我可以使用CONTAINSTABLE进行条件连接(仅当为@pSearchFor参数指定了值时)吗?我不知道如何实现这一目标.非常感谢任何指针.

Sep*_*eph 0

当您搜索空值或 null 值时,您期望得到什么?您希望查询不返回任何内容,还是希望它返回其他内容。

如果你希望它不返回任何内容,那么你最好这样做:

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
Run Code Online (Sandbox Code Playgroud)

编辑:修复现在在提供 null 或空字符串时返回所有记录。

如果您有超过 2 个具有不同搜索字符串的 CONTAINS 表查询,那么我建议您使用动态 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]
Run Code Online (Sandbox Code Playgroud)

这应该可以为您提供所需的内容,而不必重复某些内容,但是您可能希望进一步限制输入 #temp 表的结果,因为对于较大的表来说,它会变慢。