Django MySql原生查询错误 - 参数索引超出范围
这个视图在普通的Python/Django/mysql环境下运行得很好。
我正在把它移植到jython/Django/mysql上,但出现了错误。
Exception received is : error setting index [10] [SQLCode: 0]
Parameter index out of range (10 > number of parameters, which is 0). [SQLCode: 0],
[SQLState: S1009]
这个查询是 -
cursor.execute("select value from table_name
where value_till_dt >= str_to_date('%s,%s,%s,%s,%s', '%%m,%%d,%%Y,%%H,%%i')
AND value_till_dt <= str_to_date('%s,%s,%s,%s,%s', '%%m,%%d,%%Y,%%H,%%i')
and granularity='5'
ORDER BY value_till_dt",
[int(tempStart.month),int(tempStart.day), int(tempStart.year), int(tempStart.hour), int(tempStart.minute),
int(tempEnd.month), int(tempEnd.day), int(tempEnd.year), int(tempEnd.hour), int(tempEnd.minute)])
你可以看到,这个查询传入了10个参数。
这个错误是否意味着查询没有接收到这些参数呢?
我在执行之前打印了这些参数,显示它们确实被正确传递了 -
1 - Start Parameters being passed are : 1 11 2010 10 0
2 - End Parameters being passed are : 1 11 2010 10 5
第二个环境唯一不同的是,这个日期范围内没有可用的数据。但这个错误似乎和数据没有关系。
任何想法都很受欢迎。
2 个回答
0
你确定参数标记是 %s
而不是 ?
或者 :parameter
吗?可以查看一下 DB-API 模块的 paramstyle
参数来确认一下。
2
这确实是一个参数格式的问题。你需要用 ? 来代替 %s。
下面是你如何重现你遇到的错误:
shell> jython
>>> from com.ziclix.python.sql import zxJDBC
>>> (d, v) = "jdbc:mysql://localhost/test", "org.gjt.mm.mysql.Driver"
>>> cnx = zxJDBC.connect(d, None, None, v)
>>> cur = cnx.cursor()
>>> cur.execute("SELECT %s", ('ham',))
..
zxJDBC.Error: error setting index [1] [SQLCode: 0]
Parameter index out of range (1 > number of parameters,
which is 0). [SQLCode: 0], [SQLState: S1009]
现在,如果你在 ? 符号周围加上引号,你会遇到同样的问题:
>>> cur.execute("SELECT '?'", ('ham',))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
zxJDBC.Error: error setting index [1] [SQLCode: 0]
Parameter index out of range (1 > number of parameters,
which is 0). [SQLCode: 0], [SQLState: S1009]
关键是不要使用引号,让数据库接口来处理这个问题:
>>> cur.execute("SELECT ?", ('ham',))
>>> cur.fetchall()
[(u'ham',)]
这是我在代码中会怎么做。你首先要像这样准备好要用在 str_to_date() 函数中的字符串:
start = "%d,%d,%d,%d,%d" % (int(tempStart.month),
int(tempStart.day), int(tempStart.year),int(tempStart.hour),
int(tempStart.minute))
stop = "%d,%d,%d,%d,%d" % (int(tempEnd.month),
int(tempEnd.day), int(tempEnd.year), int(tempEnd.hour),
int(tempEnd.minute))
你写出 SELECT 语句,但不要使用任何引号,然后把它传给游标。数据库接口会为你完成这个工作。此外,我们把 'granularity' 的值作为一个参数。
select = """SELECT value FROM table_name
WHERE value_till_dt >= str_to_date(?, '%%m,%%d,%%Y,%%H,%%i')
AND value_till_dt <= str_to_date(?, '%%m,%%d,%%Y,%%H,%%i')
AND granularity=?
ORDER BY value_till_dt
"""
cursor.execute(select, (start,stop,5))
希望这能帮到你!