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
答案 0 :(得分:10)
在你的代码中,你正在使用%s
这是python substition字符串语法,它需要在同一行上的替换值,例如
sql = sql + " WHERE CAT_ID = %s
AND COMMONS_ID = %s " % (p_CAT_ID, p_COMMONS_ID)
然而,这(如前所述)并不是最好的方法,因为(a)它可能是一个SQL注入漏洞; (b)由于每次调用都需要对新SQL语句进行硬解析,因此可能会导致数据库性能不佳。
相反,您应该使用Oracle Bind变量语法,例如:
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
上面的示例使用位置绑定,即第一个参数绑定到第一个绑定占位符,列表中的第二个参数绑定到第二个占位符。
更好的方法是使用dict按名称为特定绑定变量赋值。当很难知道占位符添加到查询中的顺序,并使代码更易于阅读和维护时,这非常有用:
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