我正在尝试将由字符分隔的字符串传递给存储过程,而我想要做的是对这些字执行SELECT,以便每个后续SELECT在其之前查询结果集。我一直在研究如何使用递归CTE实现这一点,但我无法找到一种正确的方法来设置锚点和终结符以使递归正常工作。我知道我可以在我的服务器端代码(C#)上执行此操作,但我很乐意不必重复调用DB,因为我知道可以在那里完成。下面是存储过程,减去任何拆分类型的操作以拆分字符串和我所做的任何黑客递归尝试(即它所做的只是返回一个关键字的结果集):
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]
答案 0 :(得分: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