SQL Server:在具有动态列名的存储过程中动态生成select语句

时间:2013-10-19 13:11:40

标签: sql stored-procedures sql-server-2008-r2

我想在SQL Server存储过程中生成一个select语句。我在SQL参数中有列名。

我正在尝试使用选定的列名以编程方式生成select语句,但似乎无法在存储过程中找到正确的语法。

CREATE PROCEDURE dbo.aProc
     @testCondition int,
     @colCount int,
     @column_1 varchar(100) = null,
     ....
    @column_40 varchar(100) null
AS
  DECLARE @qry nvarchar(3000)
  DECLARE @Iterator int

  SET @testtype = 2
  SET @Iterator = 0
  SET @qry  ='SELECT '

  WHILE (@Iterator < @colCount-1)
    BEGIN
        SET @qry = @qry + ''+@column_''+CAST(@Iterator as varchar(2))+',''
        Set @Iterator = @Iterator + 1
    END


  SET @qry = @qry + ''@column_+CAST(@colCount as varchar(2)) FROM aTable where aCol = @testCondition 

2 个答案:

答案 0 :(得分:0)

这似乎是一个糟糕的主意(obligatory sql injection link)和可能的替代方案

要回答这个问题,请执行以下操作。

DECLARE @sql VARCHAR(MAX)

SET @sql = 'SELECT ' + 
               ISNULL(@col1, '') + ', ' +
               ISNULL(@col2, '') + ', ' +
               ISNULL(@col3, '') + ', ' +
               ISNULL(@col4, '') + ', ' +
               ISNULL(@col5, '') + ', ' +
               -- ...
           'FROM tbl WHERE ' ...

通过这种方式做到这一点的努力要少 - 或者正如评论所暗示的那样 - 而不是搞乱循环(这对你来说已经远远不够了)。

老实说虽然你似乎更好地使用内联函数

CREATE FUNCTION dbo.vSomeTable
    (@id INT)
RETURNS TABLE
AS
RETURN (
    SELECT * FROM tbl WHERE condition = @id
)

然后让用户做

SELECT col1, col2, col2 FROM dbo.vSomeTable(4)

更好
EXEC dbo.aProc @condition=1, @col1='col1', @col2='col2'

答案 1 :(得分:0)

CREATE PROCEDURE dbo.aProc
    @tablename varchar(100),
     @testCondition int,
     @colCount int,
     @column_1 varchar(100) = '',
     ....
    @column_40 varchar(100) ''
AS
BEGIN
if object_id('tempdb..#t') is not null
drop table #t


select 
table_name
,column_name
into #t
from information_schema.columns
where table_name=@tablename
and column_name in 
(@column_1,@column_2,@column_3,@column_4,@column_5
.....
@column_36,@column_37,@column_38,@column_39,@column_40)

select 
  'select '+
  stuff((
    select ', ' + 'isnull('+t2.column_name+','''') as' +t2.column_name+CHAR(10)
    from #t t2
    where t2.table_name = #t.table_name
    for xml path (''))
,1,2,'')+' from ' +#t.table_name
from #t
group by #t.table_name

END

我不是 LOOP 的崇拜者。实际上我讨厌循环查询。