2012-01-12 127 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