5

下面是我的 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]

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

我可以使用 CONTAINSTABLE 进行条件连接吗(仅当为 @pSearchFor 参数指定了值时)?我不确定如何实现这一目标。将不胜感激任何指针。

4

3 回答 3

2
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

我刚刚解决了完全相同的问题,并想帮助你。

于 2011-06-20T23:03:12.477 回答
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 个具有不同搜索字符串的 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]

这应该会给你你想要的东西,而不必复制东西,但是你可能想要更多地限制输入 #temp 表的结果,因为它对于更大的表会变慢。

于 2011-05-03T22:50:19.980 回答
-1

我也有完全相同的问题,并通过在所有记录的搜索索引列中添加/附加一个虚拟关键字“fts”来解决它。

if(nullif(@pSearchFor,'') is null)
begin
     set @pSearchFor= 'fts';                
end
于 2011-12-22T21:33:09.710 回答