2012-01-12 122 views
1

我試圖傳入一個存儲過程的字符串,由空格分隔,我想要做的是對這些字執行SELECT,以便每個後續SELECT查詢結果在它之前設置。我一直在研究如何用遞歸CTE來實現這一點,但我無法弄清楚設置錨點和終止符以使遞歸正常工作的正確方法。我知道我可以在我的服務器端代碼(C#)上做到這一點,但我很樂意不必重複調用數據庫,以瞭解我可以在其中完成的任何事情。下面是存儲過程,減去分體式操作來了分割字符串和我所做的任何黑客企圖遞歸(即,它的作用是返回結果集爲一個關鍵字):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

你說的意思是「每個後續的SELECT查詢結果之前將其設爲」。在非TSQL方面你有什麼要完成? – Paparazzi 2012-01-12 19:36:15

+0

你能提供@searchQuery樣本值,在RolodexTestDB一些示例數據,以及期望的結果?否則很難解釋你正在嘗試做什麼 – 2012-01-12 20:19:02

+0

對不起 - 我的錯誤解釋。 @searchQuery的示例值可能是:「血液HIV白色」 - 我需要的是執行上述查詢3次(或其他解決方案實現相同的功能) - 每次運行查詢時,結果集爲(第一次運行時,我得到包含第一項的任何記錄;然後我再次在第二項上運行該結果集上的查詢,以此類推等等)。 希望有道理。 – user1007918 2012-01-12 22:57:45

回答

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