包含函数的SQL Server动态列表

时间:2009-10-13 21:44:01

标签: sql sql-server tsql sql-server-2008

我在SQL Server 2008中有一个数据库表,其中包含5个nvarchar(max)列。我们使用CONTAINS函数在这些列中查找文本。

我们可以使用这种查询查看所有五列:

SELECT *
FROM SomeTable ST
WHERE CONTAINS( (ST.ColumnA, ST.ColumnB, ST.ColumnC, ST.ColumnD, ST.ColumnE) , '"Strawberry"')

现在我们想要动态搜索这些列中的一个或多个列的文本。例如,只查看ColumnB和ColumnE。我尝试使用CASE语句,但我不能。

我能想到的唯一解决方案是动态SQL,但我更愿意避免这种情况。 (完整查询非常复杂。)有没有办法在不使用动态SQL的情况下执行此操作?

3 个答案:

答案 0 :(得分:1)

我能想到避免使用动态SQL的唯一方法是使用临时表和if语句以及存储过程。为每个列包含一个存储过程,其中包含要搜索该列的文本。创建临时表或表变量以存储中间结果。

每个可能的列都有五个不同的if语句。如果变量不为null,则在每个if中插入临时表。类似的东西:

IF @ColA is not null
BEGIN
INSERT INTO #temp
SELECT * FROM SomeTable ST
        WHERE CONTAINS( (ST.ColumnA) , @ColA)
END

最后从临时表中选择以显示结果。

这只能很好地工作,但如果你没有很多列,并且不太可能添加更多列。坦率地说,你有多个列需要对同一个搜索字符串进行全文搜索这一事实向我表明你可能在数据库设计方面存在基本问题。

答案 1 :(得分:0)

我可以在这样的解决方案中思考,但这不会使用全文搜索...让我知道它是否对您有用。

SELECT *
FROM SomeTable ST
WHERE 1=1
AND ((@colA = '') OR ST.ColumnA LIKE @colA)
AND ((@colB = '') OR ST.ColumnB LIKE @colB)
AND ((@colC = '') OR ST.ColumnC LIKE @colC)
AND ((@colD = '') OR ST.ColumnD LIKE @colD)
AND ((@colE = '') OR ST.ColumnE LIKE @colE)

search_on参数为bit(0,1),因此,当设置为1时,将激活对该列的搜索。

答案 2 :(得分:0)

你可以联合5个案件,然后PIVOT并连接。我不确定它是否比动态SQL更好。

你最终会得到类似的东西:

SET @FindKey = '%B%E%' -- This is your search which field criteria

WITH RESULTS1 AS (
    SELECT PK, 'A' AS Col
    FROM SomeTable ST
    WHERE @FindKey LIKE '%A%' AND CONTAINS(ST.ColumnA, '"Strawberry"')
    UNION
    SELECT PK, 'B' AS Col
    FROM SomeTable ST
    WHERE @FindKey LIKE '%B%' AND CONTAINS(ST.ColumnB, '"Strawberry"')
    UNION
    SELECT PK, 'C' AS Col
    FROM SomeTable ST
    WHERE @FindKey LIKE '%C%' AND CONTAINS(ST.ColumnC, '"Strawberry"')
    UNION
    SELECT PK, 'D' AS Col
    FROM SomeTable ST
    WHERE @FindKey LIKE '%D%' AND CONTAINS(ST.ColumnD, '"Strawberry"')
    UNION
    SELECT PK, 'E' AS Col
    FROM SomeTable ST
    WHERE @FindKey LIKE '%E%' AND CONTAINS(ST.ColumnE, '"Strawberry"')
)
,RESULTS2 AS (
SELECT PK, ISNULL([A], '') + ISNULL([B], '') + ISNULL([C], '') + ISNULL([D], '') + ISNULL([E], '') AS FoundKey
FROM RESULTS PIVOT ( MIN(Col) FOR Col IN ([A], [B], [C], [D], [E]) ) AS pvt
)
SELECT *
FROM SomeTable
INNER JOIN RESULTS2
    ON RESULTS2.PK = SomeTable.PK
WHERE RESULTS2.FoundKey LIKE @FindKey