以下是我的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中也看到了question,但它对我没有帮助。
我可以使用CONTAINSTABLE进行条件连接(仅当为@pSearchFor参数指定了值时)吗?我不知道如何实现这一目标。非常感谢任何指针。
答案 0 :(得分: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
我刚解决了完全相同的问题,并想到帮助你。
答案 1 :(得分: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
edit:fixed to now返回所有记录,当提供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表中,因为对于较大的表来说它会变慢。
答案 2 :(得分:-1)
我也有完全相同的问题,并通过在所有记录的搜索索引列中添加/附加虚拟关键字'fts'来解决它。
if(nullif(@pSearchFor,'') is null)
begin
set @pSearchFor= 'fts';
end