当我用variab替换硬编码值时,Python SQL查询返回“ORA00936:missing expression”

2024-10-01 09:16:29 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个充满信息的数据库,我正在尝试编写一个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错误。我不明白为什么查询是用硬编码的值来完成的,但当值被一个变量(在前一个查询中起作用的变量)替换时就不明白了。提前谢谢。你知道吗


Tags: fromexecutebywhereleftselectcursorjoin
1条回答
网友
1楼 · 发布于 2024-10-01 09:16:29

需要修复cursor.execute的语法,例如

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]))

相关问题 更多 >