генерировать предложение where динамически с динамическими именами столбцов - PullRequest
1 голос
/ 10 августа 2010

У меня есть данные в таблице SQL 2005, как показано ниже.

Table Name: FilterData
CategoryID ColumnID  AnswerCode
--------------------------------
0349       Q15       02
0349       Q15       03
0349       Q16       04
Table Name: TransactionData
CategoryID Q15
---------------------------------
0349       01  
0349       02
0349       03
0349       04
0349       05
0349       06

Таблица FilterData содержит информацию о том, какие столбцы будут использоваться для фильтрации операторов выбора в TransactionData. Поэтому, когда я выполняю Select * из TransactionData, я хочу построить выражение Where из таблицы FilterData, чтобы я мог запустить его в таблице TransactionData для этого CategoryID.

Может кто-нибудь, пожалуйста, помогите мне, как я могу это сделать?

Ответы [ 2 ]

2 голосов
/ 11 августа 2010

Если я правильно понимаю ваш вопрос, приведенный ниже код должен работать.Обратите внимание, что я создал функцию, которая поможет с конкатенацией строк.Я не уверен, хотите ли вы И или ИЛИ ваши условия.Я использовал AND в моем образце.Вы можете легко настроить его для ИЛИ, если это подходит.

/* 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
0 голосов
/ 10 августа 2010

Это пункт where для вышеуказанных критериев. Однако вам нужно уточнить, что вы подразумеваете под динамикой? Будете ли вы получать 2 набора из двух критериев - то есть (Q15 и '02', '03') и ('Q16' и '04')? Кроме того, вы должны сделать эти параметры запроса для предотвращения SQL-инъекций.

Где

(

ColumnId = 'Q15' и answerCode IN ('02 ',' 03 ')

)

OR

(

ColumnId = 'Q16' и answerCode IN ('04 ')

)

...