Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/323.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python SQL查询返回;ORA-00936:缺少表达式;当我用变量替换硬编码值时_Python_Python 3.x_Oracle_Cx Oracle_Python Sql - Fatal编程技术网

Python SQL查询返回;ORA-00936:缺少表达式;当我用变量替换硬编码值时

Python SQL查询返回;ORA-00936:缺少表达式;当我用变量替换硬编码值时,python,python-3.x,oracle,cx-oracle,python-sql,Python,Python 3.x,Oracle,Cx Oracle,Python Sql,我有一个充满信息的数据库,我正在尝试编写一个python脚本,它将提取一些数据并将其组织到一个报告中。以下是我目前掌握的情况: import cx_Oracle import pandas as pd conn = cx_Oracle.connect('REDACTED') cursor = conn.cursor() # Currently hard-coded to return single known motor number cursor.execute('SELECT MOTOR

我有一个充满信息的数据库,我正在尝试编写一个python脚本,它将提取一些数据并将其组织到一个报告中。以下是我目前掌握的情况:

import cx_Oracle
import pandas as pd

conn = cx_Oracle.connect('REDACTED')
cursor = conn.cursor()

# Currently hard-coded to return single known motor number
cursor.execute('SELECT MOTORID FROM MOTORS WHERE SERIALNUM=804')
# Returns [(11)]
lMotorID = cursor.fetchall()

# Query Assessments for list of how long the motor had run when assessment was taken
cursor.execute("SELECT DISTINCT RUNHOURS FROM ASSESSMENTS WHERE MOTORID = %s \
               ORDER BY RUNHOURS" % lMotorID[0])
# Returns [(0), (0.91), (8), (25), ...]
lHours = cursor.fetchall()

# Query for number of installed sensors by senor type
cursor.execute("SELECT SENSTYP, COUNT(STATUS) FROM HEALTH LEFT JOIN INSTRUMENTATION \
               ON HEALTH.INSTROID = INSTRUMENTATION.INSTROID LEFT JOIN ASSESSMENTS \
               ON HEALTH.ASSESSID = ASSESSMENTS.ASSESSID WHERE ASSESSMENTS.ASSESSID \
               IN (SELECT ASSESSID FROM ASSESSMENTS WHERE MOTORID = 11 AND RUNHOURS = %s) \
               GROUP BY SENSTYP ORDER BY SENSTYP" % lHours[2])
# Returns a 2-column dataframe with sensor type in column 0 and the total in column 1
dfTotal = pd.DataFrame(cursor.fetchall())
因为我希望它适用于任何电机,所以我想用一个变量替换硬编码的
MOTORID=11
。我尝试用以下内容替换上一个查询:

cursor.execute("SELECT SENSTYP, COUNT(STATUS) FROM HEALTH LEFT JOIN INSTRUMENTATION \
               ON HEALTH.INSTROID = INSTRUMENTATION.INSTROID LEFT JOIN ASSESSMENTS \
               ON HEALTH.ASSESSID = ASSESSMENTS.ASSESSID WHERE ASSESSMENTS.ASSESSID \
               IN (SELECT ASSESSID FROM ASSESSMENTS WHERE MOTORID = %s AND RUNHOURS = %s) \
               GROUP BY SENSTYP ORDER BY SENSTYP" % (lMotorID[0], lHours[2])) 
dfTotal = pd.DataFrame(cursor.fetchall())

这就是我得到ORA-00936错误的时候。我不明白为什么查询是用硬编码的值来完成的,但当值被变量(在前一个查询中起作用的变量)替换时就不是了。提前感谢。

需要修复
游标的语法。执行

cursor.execute('... WHERE MOTORID = :mt_id AND RUNHOURS = :run_hr', mt_id=lMotorID[0][0], run_hr=lHours[2][0])
以百分号作为参数前缀对于通过python的MySQL连接是有效的,而Oracle接受冒号

或者另一个选项是使用有序元组:

cursor.execute('... WHERE MOTORID = :1 AND RUNHOURS = :2', (lMotorID[0][0],lHours[2][0]))

如需进一步阅读,请参阅文档:True,never format query inline with%,它至少会导致SQL注入漏洞。我尝试了这两个选项,两次都得到了“NotSupportedError:TypeTuple的Python值不受支持”。我尝试了Python 3.6.5 ad Oracle DB 12.1.0.2,没有任何选项存在问题。顺便说一句,第三个选项可能是使用括号来包装元组,例如
[lMotorID[0],lHours[2]]
@smperonaside从使用绑定变量的角度出发,尝试打印变量,或者执行
try catch
和打印
Cursor.statement
来查看正在运行的查询。我怀疑您的
lmotroid[0]
实际上是空的。@kfinity那么为什么
lmotroid[0]
在第二次查询(开始
#查询评估
)中起作用?很好,您可能有不同的问题。我仍然建议打印变量和/或完整查询。进行
尝试,最后除外
肯定有帮助。将
print(cursor.statement)
添加到
except
块后,我发现它传递的是元组而不是值。在每个变量得到实际值后添加
[0]
,然后查询工作。谢谢