我有一个存储在变量中的SQL语句:
我使用文件操作
从“.sql”文件中获取此“语句”set statement "SELECT build_package,
replace(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(substring(build_package, length(build_package) - position('/' in reverse(build_package)) + 2), '-BSD',''),'-LNX',''),'-esxi',''),'.repo',''),'.vmdk',''),'.qcow2',''),'.rpm',''),'.tbz',''),'-version',''),'.el7.x86_64','') ,'-NR',''),'-kvm',''),'-x86_64',''),'ptsvpl','svpts'),'spbvpl','svspb'),'sdevpl','svsde'),'-amd64',''),'.noarch',''),'.el6',''),'.x86_64',''),'tsevpl','svtse')
FROM scheduler_jobs WHERE id = '1617075' order by id DESC"
这里的where子句是例如:WHERE id = 1617075
id是动态生成的。
所以我需要先存储没有WHERE id = 1617075
子句的 sql ,然后在'statement'变量中加入where子句。
基本上在语句中添加一些名为$id
的数据。
答案 0 :(得分:2)
使用带有绑定变量的prepared statement。
文档中的示例:
set statement [db prepare {
select phone_num from directory
where first_name = :firstname and last_name = :lastname
}]
set firstname Fred
set lastname Flintstone
正如文档所解释的那样,
针对连接的准备对象命令接受对数据库执行的任意SQL代码。 SQL代码可能包含绑定变量,它们是字母数字字符或下划线的字符串(字符串的第一个字符可能不是数字),前缀为冒号(:) 。如果绑定变量出现在SQL语句中,并且不在由单引号或双引号引发的字符串中,也不在 - 引入的注释中,则它将成为在语句中替换的值被执行。绑定变量在结果语句中变为单个值(字符串或数字) 驱动程序负责确保绑定变量的机制阻止SQL注入。
换句话说,虽然 是驱动程序的责任,但应该防止SQL注入。换句话说,如果id
不仅仅是1617075
而是1617075; DROP TABLE scheduler_jobs;--
,那么你应该还可以,因为驱动程序已正确转义了这个(而不是你必须这样做,错过了让你容易受到伤害的边缘案例。
对于你的例子,省略所有REPLACE
,这将成为
set statement [db prepare {
SELECT build_package
FROM scheduler_jobs
WHERE id = :scheduler_job_id
ORDER BY id DESC
}]
set scheduler_job_id 1617075
答案 1 :(得分:0)
只需使用字符串映射。
首先将字符串保存为带有标记的模板,然后删除要替换的任何部分:
set statement "SELECT build_package,
replace(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(substring(build_package, length(build_package) - position('/' in reverse(build_package)) + 2), '-BSD',''),'-LNX',''),'-esxi',''),'.repo',''),'.vmdk',''),'.qcow2',''),'.rpm',''),'.tbz',''),'-version',''),'.el7.x86_64','') ,'-NR',''),'-kvm',''),'-x86_64',''),'ptsvpl','svpts'),'spbvpl','svspb'),'sdevpl','svsde'),'-amd64',''),'.noarch',''),'.el6',''),'.x86_64',''),'tsevpl','svtse')
FROM scheduler_jobs <WHERE_CLAUSE> order by id DESC"
此处我选择的代码是 ,但您可以使用自己喜欢的内容。
然后:
set query_cmd [string map {<WHERE_CLAUSE> "WHERE id = '123456'"} $statement]
puts $query_cmd
这可以针对您需要更改的字符串的许多不同部分完成,只需使用另一个标记。
set query_cmd [string map {<TAG1> $v1 <TAG2> $v2...} $statement]
您当然可以在字符串中加入一个引用变量,如:
...WHERE id = '\$id'...
然后使用 subst ,但我认为在这种情况下字符串映射可能更有用。