Python参数传递防止SQL注入,为什么会报错?
在编程中,有时候我们需要在代码里使用一些特定的符号或字符,这些符号可能会影响代码的运行。比如,某些字符在代码中有特殊的意义,像是用来表示开始或结束某个操作的符号。
为了避免这些符号造成的困扰,我们可以使用转义字符。转义字符就像是一个小助手,它告诉计算机:“嘿,这个符号我不是要让你执行它的特殊功能,而是想把它当作普通字符来处理。”
举个例子,如果我们想在代码里写一个双引号("),但又不想让它被当作字符串的开始或结束符号,我们就可以在它前面加一个反斜杠(\),这样计算机就会明白我们只是想显示这个双引号,而不是用它来结束字符串。
总之,转义字符帮助我们在代码中安全地使用那些有特殊意义的符号,让我们的代码能够顺利运行而不出错。
from django.db import connection, transaction
def pk_dt_catalog(p_CAT_ID,p_COMMONS_ID):
c1 = connection.cursor()
sql = "SELECT COMMONS_ID, CAT_ID, CAT_NAME
FROM DT_CATALOG"
sql = sql + " WHERE CAT_ID = %s
AND COMMONS_ID = %s "
param =(p_CAT_ID, p_COMMONS_ID)
c1.execute(sql, param)
return c1
>>> c = dt_catalog.pk_dt_catalog(513704,401)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "dt_catalog.py", line 24, in pk_dt_catalog
c1.execute(sql,(p_CAT_ID, p_COMMONS_ID,))
cx_Oracle.DatabaseError: ORA-01036: illegal variable name/number
1 个回答
在你的代码中,你使用了%s
,这是Python中一种替换字符串的写法,它要求替换的值在同一行上,比如:
sql = sql + " WHERE CAT_ID = %s
AND COMMONS_ID = %s " % (p_CAT_ID, p_COMMONS_ID)
不过,这种做法(之前已经提到过)并不是最好的,因为(a)它可能会导致SQL注入漏洞;(b)每次调用都需要重新解析新的SQL语句,这样会影响数据库的性能。
所以,你应该使用Oracle的绑定变量语法,比如:
c1 = connection.cursor()
sql = "SELECT COMMONS_ID, CAT_ID, CAT_NAME
FROM DT_CATALOG"
sql = sql + " WHERE CAT_ID = :foo
AND COMMONS_ID = :bar "
param = (p_CAT_ID, p_COMMONS_ID)
c1.execute(sql, param)
return c1
更多信息请查看:http://guyharrison.squarespace.com/blog/2010/1/17/best-practices-with-python-and-oracle.html
上面的例子使用了位置绑定,也就是说,第一个参数绑定到第一个占位符,第二个参数绑定到第二个占位符。
一种更好的方法是使用字典,通过名称将值分配给特定的绑定变量。当你不确定占位符添加到查询中的顺序时,这种方法特别有用,同时也让代码更容易阅读和维护:
c1 = connection.cursor()
sql = "SELECT COMMONS_ID, CAT_ID, CAT_NAME
FROM DT_CATALOG"
sql = sql + " WHERE CAT_ID = :foo
AND COMMONS_ID = :bar "
param = {"foo": p_CAT_ID, "bar": p_COMMONS_ID}
c1.execute(sql, param)
return c1
更多示例和教程请查看:http://st-curriculum.oracle.com/obe/db/11g/r2/prod/appdev/opensrclang/pythonhol2010_db/python_db.htm