动态SQL中的区别黑白字符串连接和绑定变量

Cza*_*zar 1 sql oracle plsql

差不多的头衔。我想知道字符串连接之间在行为和性能上是否存在差异

var_name := 'SKING';
sql := 'select * from emp where ename = ' || var_name;
execute immediate sql;
Run Code Online (Sandbox Code Playgroud)

并绑定变量

sql := 'select * from emp where ename = :1';
execute immediate sql
using var_name;
Run Code Online (Sandbox Code Playgroud)

在动态SQL中。谢谢!

Cai*_*ard 6

如果var_name包含类似以下的字符串,则行为上可能存在巨大差异

'A' AND 1=2 UNION SELECT password, null, null ... FROM users WHERE username='admin'
Run Code Online (Sandbox Code Playgroud)

在第一个示例中,您可能只是操纵数据库转储了管理员密码(哈希)或其他敏感信息。如果将此操作作为绑定变量完成,那么您将获得0行,除非确实有一个员工的名字'A' AND 1=2 UNION ...

如果您的员工姓名无害Peter O'Toole或其他带有合法的'字符,则第一个查询甚至会导致崩溃

https://bobby-tables.com详细介绍了有关SQL注入黑客的知识

总是,总是,总是使用绑定变量。从未有字符串串联的借口到一个查询时,你可以连接一个变量名中,而不是

-

至于性能,如果它知道查询的哪些部分可能发生变化以及哪些部分是固定的,则可以帮助数据库查询优化器计划查询和缓存执行计划。如果将值连接在一起,则无法分辨下一次声明的内容可能会有所不同,而下一次保持不变

SELECT * FROM emp WHERE emp_type = 'manager' and emp_name = :name
Run Code Online (Sandbox Code Playgroud)

上面,优化器可以轻松推断出此查询将始终仅返回管理器类型,尽管名称可能有所不同。这可能会影响数据访问和索引策略,并且可能会对性能产生影响。很难具体说明,因为优化器是一个黑匣子。但请放心,由于良好的旧资本主义/市场力量(谁购买了缓慢的数据库?),它会努力从可用的信息中提供最佳性能,因此请予以帮助。