5

以下は、全文検索にCONTAINSTABLEを使用する SQL クエリの簡易バージョンです。

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 パラメータに空または null の値を渡したいです。しかし、空または null 値を渡すと、 「Null または空の全文述語」エラーが発生します。グーグルで調べたところ、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

空または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

編集:nullまたは空の文字列が指定されたときにすべてのレコードを返すように修正されました。

異なる検索文字列を持つCONTAINSテーブルクエリが2つ以上ある場合は、ほぼ同じクエリの2 ^ nチェーンよりも保守がはるかに簡単であるため、動的SQLを使用してクエリを生成することをお勧めします。

編集:次のような一時テーブルを使用して、複数のコピーを使用せずにこれを行う方法を検討しました:

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 に答える