为什么SQL基于文本?

时间:2014-01-21 02:29:23

标签: sql exec sql-injection object-oriented-database

我认为这并不适合我们的Q& A格式"但不知道还能在哪里问它。

为什么基于SQL查询文本?有历史动机,还是懒惰?

mysqli_query("SELECT * FROM users WHERE Name=$name");

它打开了如上所述的大量愚蠢错误,鼓励SQL注入。它基本上是exec用于SQL,并且exec代码,特别是动态生成的代码,被广泛劝阻。 另外,说实话,准备好的陈述似乎只是一个冗长的解决方法。

为什么我们没有更多面向对象,无法注入的方式,比如使用某些方法可以直接访问数据库对象:

$DB->setDB("mysite");
$table='users';
$col='username';
$DB->selectWhereEquals($table,$col,$name);

数据库本身本机实现的目标,完全消除了与exec的所有相似之处,并使SQL注入的整个基础无效。

最终真正的问题是,是否有任何数据库框架可以做这样的事情?

1 个答案:

答案 0 :(得分:4)

为什么编程语言是基于文本的?非常简单:因为文本可以用来表示强大的人类可读/可编辑的DSL(Domain-specific language),例如SQL。

更好的(?)问题是:为什么程序员拒绝使用占位符?

现代数据库提供程序(例如ADO.NET,PDO)支持占位符和适当范围的数据库适配器 1 。没有利用这种支持的程序员只能自责。

除直接数据库提供程序中的无处不在的占位符支持外,还有许多不同的API,包括:

  • “流利的数据库”;这些通常将AST(例如LINQ)映射到动态生成的SQL查询中,并处理诸如正确使用占位符之类的详细信息。
  • 各种ORMs;可能包括也可能不包括流畅的API。
  • Android SQLite API中的原始CRUD包装,看起来与提案非常相似。

喜欢 SQL的强大功能几乎所有我写的查询都不能用如此简单的API来表达。即使LINQ,它是一个强大的提供者,有时也会妨碍我(尽管审慎使用Views有帮助)。


1 即使SQL是基于文本的(并且用于将查询的形状传递给后端),也不需要包含绑定数据内联,这是SQL注入问题(能够更改查询的形状)的问题。数据库适配器可以,如果足够聪明,可以使用暴露的API由目标数据库。对于SQL Server,这相当于[通过RPC]单独发送数据;对于SQLite,这意味着创建和绑定单独的预准备语句对象。