2012-01-12 15 views
1

私は、スペースで区切られた単語の文字列をストアドプロシージャに渡そうとしています。私がしたいのは、それらの単語に対してSELECTを実行し、それの前に設定します。私は再帰的なCTEでそれを達成する方法を検討してきましたが、再帰が適切に動作するようにアンカーとターミネータを設定する適切な方法を理解することはできません。私は私のサーバー側のコード(C#)でこれを行うことができます知っているが、私はそこに行うことができます知っている何かのためのDBに繰り返し呼び出しを行う必要はありませんしたいです。以下は、最大文字列と私が作った任意のハック再帰試みを分割するストアドプロシージャ、マイナスの操作のいずれかの分割型(すなわち、それがない、すべてが一つのキーワードの結果セットを返す場合)である:SQLクエリ - 再帰的な調整

ALTER PROCEDURE searchTests 

@searchQuery varchar(200) 

AS 

SELECT 
    TestID, [Test Name], [Specimen Type], Methodology, [Performing Lab] 
FROM RolodexTestDB 
WHERE 
    (RolodexTestDB.inactive IS NULL OR NOT RolodexTestDB.inactive = 'Yes') 
    AND (
     RolodexTestDB.[Test Name] Like '%' + @searchQuery + '%' 
     or RolodexTestDB.Methodology Like '%' + @searchQuery + '%' 
     or RolodexTestDB.[Synonyms] Like '%' + @searchQuery + '%' 
     or RolodexTestDB.[Specimen Type] Like '%' + @searchQuery + '%' 
     or RolodexTestDB.[Included Tests] Like '%' + @searchQuery + '%' 
    ) 
) 
ORDER BY [Test Name] 
+1

あなたが達成しようとしているもの以外TSQL用語では。「以降の各SELECTは、その前に、結果セットを照会」とはどういう意味ですか? – Paparazzi

+0

あなたは@searchQueryのサンプル値を提供することができ、RolodexTestDBでいくつかのサンプルデータ、そして望みの結果?それ以外の場合、あなたがしようとしていることを正確に解釈することは難しいです。 –

+0

申し訳ありません - 私のところでは悪い説明。 @searchQueryのサンプル値は次のようになります: "blood HIV white" - 私が必要とするのは、上記のクエリを3回(または同じことを実現する他の解決策)実行することです - クエリが実行されるたびに、フィルタリングされています(最初の実行時に最初の用語を含むレコードが取得され、2番目の用語でその結果セットに対してクエリを実行するなど)。 それは意味があったと思います。 – user1007918

答えて

0

CONTAINS()を使用することができますようにフルテキストインデックスを使用する理想的なシナリオのように聞こえますか?

http://msdn.microsoft.com/en-us/library/ms187787.aspx

あなたは、フルテキストインデックスへのアクセス権を持っていけない場合は、そのテーブルに参加し、その後、テーブルにあなたの文字列を分割しようとすることができ、その後主キーに分割することにより(重複カウント未テストの例を。:

CREATE FUNCTION [dbo].[fnc_Split] 
    (
     @Data VARCHAR(2000) , 
     @Sep VARCHAR(5) 
    ) 
RETURNS @Temp TABLE 
    (
     Id INT IDENTITY(1, 1) , 
     Data NVARCHAR(100) 
    ) 
AS 
    BEGIN 
     DECLARE @Cnt INT 
     SET @Cnt = 1 
     WHILE (CHARINDEX(@Sep, @Data) > 0) 
      BEGIN 
       INSERT INTO @Temp 
         (data 
         ) 
         SELECT Data = LTRIM(RTRIM(SUBSTRING(@Data, 1, CHARINDEX(@Sep, @Data) - 1))) 
       SET @Data = SUBSTRING(@Data, CHARINDEX(@Sep, @Data) + 1, LEN(@Data)) 
       SET @Cnt = @Cnt + 1 
      END 
     INSERT INTO @Temp 
       (data) 
       SELECT Data = LTRIM(RTRIM(@Data)) 
     RETURN 
    END 

GO 

DECLARE @SearchString VARCHAR(MAX) 
SET @SearchString = 'blood HIV white' 

--#### Build Pattern Table 
DECLARE @PatternTable TABLE 
    (
     ID INT NOT NULL , 
     PATTERN VARCHAR(50) 
    ) 
INSERT INTO @PatternTable 
     (ID , 
      PATTERN 
     ) 
     SELECT ID , 
       CASE WHEN ID = 1 THEN Data + '%' 
        ELSE '% ' + Data + '%' 
       END AS Data 
     FROM fnc_Split(@SearchString, ' '); 

--#### Fetch list of matching Primary keys (repeat CTEs for each column) 
WITH PrepSearch (PrimaryKey, MatchedWords) 
      AS (SELECT PrimaryKey , 
         COUNT(PrimaryKey) OVER (PARTITION BY PrimaryKey) AS MatchedWords 
       FROM  dbo.RolodexTestDB P (NOLOCK) 
         INNER JOIN @PatternTable S ON P.Methodology LIKE S.PATTERN COLLATE DATABASE_DEFAULT 
      ), 
     SearchResults (PRO_CODE) 
      AS (SELECT PrimaryKey 
       FROM  PrepSearch 
       WHERE MatchedWords = (SELECT COUNT(ID) FROM @PatternTable) 
       GROUP BY PrimaryKey 
      ) 
    SELECT * 
    FROM SearchResults