【问题标题】:python cx_Oracle invalid identifierpython cx_Oracle 无效标识符
【发布时间】:2019-07-11 20:56:46
【问题描述】:

我正在尝试查询 oracle db。

import cx_Oracle

dsn_tns = '(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=some.server.com)(PORT=1521))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=service_name)))'
con = cx_Oracle.connect('USER', 'PWD', dsn_tns)

cur = con.cursor()
cur.execute('select * from admin.summary where NUMBER = "C123456"')

res = cur.fetchall()
print res

cur.close()
con.close()

得到:

$ python cx_oracle.py
Traceback (most recent call last):
  File "cx_oracle.py", line 9, in <module>
    cur.execute('select * from admin.summary where NUMBER = "C123456"')
cx_Oracle.DatabaseError: ORA-00936: missing expression

我也尝试将查询字符串更改为

'select * from admin.summary where NUMBER = 'C1012445''

得到:

$ python cx_oracle.py
  File "cx_oracle.py", line 9
    cur.execute('select * from admin.summary where NUMBER = 'C1012445'')
                                                                    ^
SyntaxError: invalid syntax

有什么建议吗? Python 版本是 2.7

【问题讨论】:

  • 试试这个cur.execute("select * from admin.summary where NUMBER = 'C123456'") 有用吗?
  • @Allan 我试过了——同样的 ORA-00936: 缺少表达式错误
  • 让我们做更多的故障排除 -> select sysdate from dual; 有效吗?也尝试不使用; 让我知道这是否有效
  • @Allan 是的,它的作品:$ python cx_oracle.py [(datetime.datetime(2019, 2, 18, 16, 10, 32),)]
  • 好的,select * from admin.summary 有效吗?另外您的 Oracle DB 版本是什么?

标签: python oracle python-2.7 cx-oracle


【解决方案1】:

NUMBER 是 SQL 中用于数据类型的保留字。默认情况下,它不会是列名,除非有人强制使用:

SQL> create table t ("NUMBER" number);

Table created.

如果他们这样做了,那么您的 SQL 还需要引用列名,例如:

cur.execute("""select "NUMBER" from t where "NUMBER" = 1""")

或者,在您的情况下,例如:

cur.execute("""select * from admin.summary where "NUMBER" = 'C123456'""")

但是,除非您始终在“where”子句中使用相同的值,否则您应该为 C123456 使用绑定变量。看看https://github.com/oracle/python-cx_Oracle/blob/master/samples/BindQuery.py 是怎么做的。

使用绑定变量有助于可扩展性并有助于阻止 SQL 注入攻击。

【讨论】:

    【解决方案2】:

    cur.execute('select * from admin.summary where NUMBER = "C123456"'

    在 SQL 中,双引号用于数据库标识符名称(表和列),而不是字符串文字。所以 Oracle 编译器正在寻找一个名为 C123456 的列。

    cur.execute('select * from admin.summary where NUMBER = 'C1012445'')

    您的字符串由单引号包围,因此它在 = 之后结束,Python 解释器不知道如何处理 C123456

    尝试像这样转义引号:

    cur.execute('select * from admin.summary where NUMBER = ''C1012445'' ')
    

    正如@ChristopherJones 所指出的,NUMBER 是一个保留字,不能用作 Oracle 中的名称。我认为发布的代码是一个编辑,但如果有人愚蠢到强行通过这样的列名,他们一定是通过使用双引号来做到这一点的。在这种情况下,对该列的所有后续引用也必须用双引号转义:

    cur.execute('select * from admin.summary where "NUMBER" = ''C1012445'' ')
    

    【讨论】:

    • NUMBER 是保留字:SQL&gt; create table t (number CHAR); create table t (number CHAR) * ERROR at line 1: ORA-00904: : invalid identifier
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-03
    • 2012-12-30
    • 1970-01-01
    相关资源
    最近更新 更多