此问题已在此处有答案:
How to use variables in SQL statement in Python?(6个回答)
上个月关门了。
我尝试在SQL查询中插入两个日期,但脚本显示以下错误:Oracle数据库中存在错误:ORA-01036:非法变量名称/编号 *
starting_date='01/01/2023'
ending_date='01/04/2023'
params = (starting_date,ending_date)
cur.execute('SELECT analisi.codice, analisi.descrizione FROM analisi LEFT JOIN ris ON analisi.codice = ris.analisi LEFT JOIN ric ON ris.richiesta_id = ric.richiesta_id WHERE ric.richiesta_ins_data >= TO_DATE(?, \'dd/mm/yyyy\') AND ric.richiesta_ins_data <= TO_DATE(?, \'dd/mm/yyyy\') AND ris01 IS NOT NULL AND ris01 NOT IN (\'N01\',\'N10\') GROUP BY analisi.codice, analisi.descrizione', params)
我试过只用一个占位符,它的工作原理
sql = "SELECT analisi.codice, analisi.descrizione FROM analisi LEFT JOIN ris ON analisi.codice = ris.analisi LEFT JOIN ric ON ris.richiesta_id = ric.richiesta_id WHERE ric.richiesta_ins_data >= TO_DATE('%s', \'dd/mm/yyyy\') AND ric.richiesta_ins_data <= TO_DATE(\'31/03/2023\', \'dd/mm/yyyy\') AND ris01 IS NOT NULL AND ris01 NOT IN (\'N01\',\'N10\') GROUP BY analisi.codice, analisi.descrizione" %starting_date
# cur.execute(sql)
我做错了什么?
1条答案
按热度按时间fumotvh31#
这个问题是使用字符串连接和插值放在首位,并不能修复任何数量的报价或净化。这就允许SQL注入攻击和转换错误,就像我们仍然在新闻中看到的那样,关于由于“计算机错误”而导致的巨额账单。那是4月1日还是1月4日?为什么有人要假设这两个日期?
一个更好、实际上更容易的选择是使用查询参数。在这种情况下,参数值永远不会转换为文本,也永远不会成为查询的一部分,甚至不会成为执行计划的一部分。这些值将不作更改地传递到数据库。数据库将查询编译为带有 * 参数的执行计划,并使用查询参数的值执行它。
在Oracle中,查询参数称为Bind Variables,可以通过名称或位置传递。使用它们会产生更干净,而不仅仅是更安全的代码:
问题的代码可以更改为: