您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

Python中准备好的语句和参数化查询之间的混淆

Python中准备好的语句和参数化查询之间的混淆

预处理语句:对数据库中预解释的查询例程的引用,准备接受参数

参数化查询:通过您的代码以这样的方式制成的查询要传递的值在 旁边 一些sql具有占位符值,通常?或者%s或那味道的东西。

这里的困惑似乎是由于(显然)在直接获取准备好的语句对象的能力与将值传递到行为很像一个“参数化查询方法的能力之间缺乏区别而引起的。因为它是一种,或者至少可以为您赚一个

例如:sqlite3库的C接口具有许多用于处理预准备语句对象的工具,但是Python api几乎没有提及它们。您无法准备一个语句并在任何时候多次使用它。相反,您可以使用sqlite3.@R_502_826@(sql, params)sql代码,在 内部 创建一个准备好的语句,然后在循环中使用该语句来处理您给出的可迭代对象中的每个参数元组

Python中的许多其他sql库的行为方式相同。使用准备好的语句对象可能会带来极大的痛苦,并可能导致模棱两可,而在像Python这样的语言中,它倾向于清晰明了,并且在原始执行速度方面也较宽松,因此它们并不是真正的最佳选择。本质上,如果您发现自己不得不对每次都需要重新解释的复杂SQL查询进行数十万或数百万次调用,那么您可能应该做不同的事情。无论如何,有时人们希望它们可以直接访问这些对象,因为如果在数据库服务器周围保留相同的准备好的语句,则不必一遍又一遍地解释相同的sql代码

总的来说,也许更重要的是预准备语句和参数化查询使您的数据保持卫生并与sql代码分开的方式。 您应该将以某种形式或另一种形式进行参数化的查询和准备好的语句视为 。如果尝试以其他方式构建sql语句,它将不仅运行速度明显降低,而且还容易受到其他问题的攻击。

*例如,通过生成要在生成函数中馈入数据库的数据,然后使用@R_502_826@()一次从生成器中插入所有数据,而不是execute()每次循环时都调用它。

编辑: 很多人看到这个答案!我还想澄清一下,许多数据库引擎也具有可使用纯文本查询语法显式构造的预准备语句的概念,然后可在客户端会话的生命周期内重用(例如,在postgres中)。有时,您可以控制是否缓存查询计划以节省更多时间。一些框架会自动使用它们(我见过Rails的ORM会积极地使用它们),有时有用,有时会在准备查询的形式存在变化时对它们有害。

同样,如果您想挑剔,则参数化查询并不 总是 在幕后使用准备好的语句;相反,如果您不希望这样做,则不要使用预先准备好的语句。他们应该尽可能这样做,但有时只是格式化参数值。这里的“准备语句”和“参数化查询”之间的真正区别实际上只是您使用的API的形状。

python 2022/1/1 18:41:44 有270人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶