我有一个表,其中包含一个存储sql函数,列名和类似代码段的列,如下所示:
ID | Columsql
1 | c.clientname
2 | CONVERT(VARCHAR(10),c.DOB,103)
这样做的原因是使用选定的行动态创建与电子表格模板匹配的主查询的结果。 EG模板1需要上述客户名称和DOB。 我的子查询是:
select columnsql from CSVColumns cc
left join Templatecolumns ct on cc.id = ct.CSVColumnId
where ct.TemplateId = 1
order by ct.columnposition
此查询的结果是2行文本:
c.clientname
CONVERT(VARCHAR(10),c.DOB,103)
我希望将这些内容传递给我的主要陈述,以便最初阅读
Select(
select columnsql from CSVColumns cc
left join Templatecolumns ct on cc.id = ct.CSVColumnId
where ct.TemplateId = 1
order by ct.columnposition
) from Clients c
但执行:
select c.clientname, CONVERT(VARCHAR(10),c.DOB,103) from clients c
显示客户名称和DOB的结果集。
到目前为止,我对'注射'的尝试都没有结果。有什么建议吗?
答案 0 :(得分:0)
你不能这样做,至少不能直接。您需要做的是,在存储过程中,构建一个包含完整SQL语句的varchar / string;你可以执行那个字符串。
declare @convCommand varchar(50);
-- some sql to get 'convert(varchar(10), c.DOB, 103) into @convCommand.
declare @fullSql varchar(1000);
@fullSql = 'select c.clientname, ' + @convCommand + ' from c,ients c;';
exec @fullSql
然而,这不是运行它的最有效方式 - 当你已经知道需要放入什么片段时,为什么不写这个语句呢?
我认为你不能这样做的原因是SQL注入是一件危险的事情。 (如果你不知道为什么请做一些研究!)将一个危险的字符串放入表中 - 例如'c.dob from clients c;drop table clients;
' - 使用包含实际执行代码的数据的列将不是一件好事!
编辑1:
原始程序员可能正在使用C#函数:
string newSql = string.format("select c.clientname, {0} from clients c", "convert...");
基本格式为:
string.format("hhh {0} ggg{1}.....{n}, s0, s1,....sn);
第一个字符串中的{0}被s0处的字符串替换; {1}将替换为s1,... {n}处的字符串替换为sn。
处的字符串这可能是一种合理的方法,但为什么需要所有碎片都有点不透明。你不能在sql中复制它,除了做我上面建议的。 (SQL没有类似于string.format函数的东西。)