SQL Server创建具有可变列的功能以进行聚合/输出

时间:2014-09-16 14:19:06

标签: sql sql-server sql-server-2008 function

假设我的SQL Server(2008)数据库中有以下两个表:

表1:

Col1:    ...   Map:
1        ...   a
2        ...   a
3        ...   b
4        ...   c
5        ...   c

映射器:

Map:     Out1:    Out2: ...
a        ab       ac
b        ab       bd
c        cd       ac
d        cd       bd   
    ... (whatever) ...

现在,我想创建一个表值函数,它将返回以下行中的内容:

SELECT 
   M.Out1, 
   SUM(T.Col1)
FROM
   Table1 as T,
   Mapper as M
WHERE
   T.Map = M.Map
GROUP BY
   M.Out1

HOWEVER 我希望能够包含一个参数,该参数可以指示返回/分组的Mapper哪一列(即不限于Out1,但也能够根据某种形式的用户输入返回可能由MapOut2等分组的查询(我假设输入col.name作为定义输入)。)

我发过帖子说你可以使用动态SQL做到这一点,但警告SQL注入......是否有更好的方法?

谢谢!

2 个答案:

答案 0 :(得分:2)

以下是基于您的示例的松散示例。注意我还将您的连接更改为ANSI-92样式连接,而不是旧的ANSI-89样式连接。这更容易阅读,更不容易发生意外交叉连接。

declare @ColumnNameParameter sysname = 'MyColumn;] that is injection safe'

declare @SQL nvarchar(max)

set @SQL = 
'select M.' + QUOTENAME(@ColumnNameParameter) 
+ ', SUM(T.Col1)
from Table1 as T
join Mapper as M on M.Map = t.Map
GROUP BY M.' + QUOTENAME(@ColumnNameParameter) 

select @SQL

答案 1 :(得分:0)

我可以告诉你两个选项:

1)使用sp_executesql并将结果存储到也动态创建的临时表中。在这种情况下,您应该能够运行'SELECT [custom column mapping columns] INTO #TEMPTable FROM [Mapped/Joined Table[s]]'

2)在SQL中使用CLR。

抱歉,我注意到我没有回应您对SQL注入的担忧。它始终需要注意,如果您担心它,那么您可以在将用户输入添加到语句之前解析用户输入。例如,您可以确保只有一个单词存在,不会延伸超过特定长度,不包含任何SQL关键字,如SELECT,UPDATE,DELETE,DROP等。