【问题标题】:generate where clause dynamically with dynamic column names使用动态列名动态生成 where 子句
【发布时间】:2011-03-27 21:22:28
【问题描述】:

我在 SQL 2005 表中有如下数据。

表名:FilterData 类别 ID 列 ID 答案代码 -------------------------------- 0349 Q15 02 0349 Q15 03 0349 Q16 04 表名:TransactionData 类别 ID Q15 --------------------------------- 0349 01 0349 02 0349 03 0349 04 0349 05 0349 06

FilterData 表包含有关哪些列将用于过滤 TransactionData 上的选择语句的信息。因此,当我从 TransactionData 执行 Select * 时,我想从 FilterData 表构建 Where 子句,以便我可以在该 CategoryID 的 TransactionData 表上触发它。

有人可以帮我看看我该怎么做吗?

【问题讨论】:

  • 不太了解您要构建什么?

标签: sql-server sql-server-2005 dynamic-sql


【解决方案1】:

如果我正确理解您的问题,下面的代码应该可以工作。请注意,我创建了一个函数来帮助进行字符串连接。我不确定您是否想要 AND 或 OR 您的条件。我在我的示例中使用了 AND。如果合适的话,你可以很容易地为 OR 调整它。

/* Set up sample data */
create table FilterData (
    CategoryID char(4),
    ColumnID char(3),
    AnswerCode char(2)
)

insert into FilterData
    (CategoryID, ColumnID, AnswerCode)
    values
    ('0349','Q15','02')
insert into FilterData
    (CategoryID, ColumnID, AnswerCode)
    values
    ('0349','Q15','03')
insert into FilterData
    (CategoryID, ColumnID, AnswerCode)
    values
    ('0349','Q16','04')
go

/* Helper function to concatenate all AnswerCodes for a given ColumnID */
create function dbo.fnStringAnswerCodes(@ColumnID char(3))
returns varchar(1000)
as
begin
    declare @CodeString varchar(1000)
    set @CodeString = @ColumnID + ' in ('

    select @CodeString = @CodeString + '''' + AnswerCode + ''','
        from FilterData
        where ColumnID = @ColumnID

    /* Remove trailing comma and add closing parens */
    select @CodeString = left(@CodeString, len(@CodeString)-1) + ')'

    return @CodeString
end
go

declare @CategoryID char(4)
declare @SQLString varchar(1000)
declare @WhereClause varchar(1000)

set @CategoryID = '0349'
set @SQLString = 'select * from TransactionData '
set @WhereClause = 'where CategoryID=''' + @CategoryID + ''' and '


select @WhereClause = @WhereClause + dbo.fnStringAnswerCodes(ColumnID) + ' and '
    from FilterData
    where CategoryID = @CategoryID
    group by ColumnID

/* Remove Trailing 'AND' */
set @WhereClause = LEFT(@WhereClause, len(@WhereClause)-3)

set @SQLString = @SQLString + @WhereClause
select @SQLString

/* Last step would be to dynamically execute the string we built */
/* exec sp_ExecuteSQL @SQLString */

/* Clean Up */
drop function dbo.fnStringAnswerCodes
drop table FilterData

【讨论】:

  • 这是我见过的最棒的答案。我仍在尝试了解这到底是做什么的,但它给了我想要的东西。非常感谢您的回答。非常感谢。
  • 很棒的答案是我的专长! :-) 很高兴我能帮上忙。
【解决方案2】:

这是上述条件的 where 子句。但是,您需要澄清动态是什么意思?您是否会收到两组两个标准 - 即(Q15 和 '02'、'03')和('Q16' 和 '04')?此外,您应该设置这些查询参数以防止 SQL 注入。

在哪里

(

ColumnId = 'Q15' 和 AnswerCode IN('02','03')

)

(

ColumnId = 'Q16' 和 AnswerCode IN('04')

)

【讨论】:

  • 我无法指定 ColumnId = 'Q15' 和 AnswerCode IN('02','03') 因为这将来自 FilterData 表,因此它必须作为字符串动态生成。 FilterData 表的 ColumnID 字段中的数据实际上是其他表的列名,而 AnswerCode 是我要过滤的值。
猜你喜欢
  • 1970-01-01
  • 2011-08-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-12
  • 2016-12-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多