假设我的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
,但也能够根据某种形式的用户输入返回可能由Map
或Out2
等分组的查询(我假设输入col.name作为定义输入)。)
我发过帖子说你可以使用动态SQL做到这一点,但警告SQL注入......是否有更好的方法?
谢谢!
答案 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等。