cx_Oracle使用绑定时返回空查询

1 投票
1 回答
1300 浏览
提问于 2025-04-17 22:36

我在使用 SQL 应用程序进行查询时遇到了一个奇怪的问题。我正在使用 Python3 和 cx_Oracle 5.1.2。我的测试表结构如下:

创建一个名为 people 的表,包含以下字段: sin CHAR(15), name VARCHAR(40), 其中 sin 是主键

我插入了以下值(sin, name):

('1','a'), ('2','b'), ('3','c')

当我使用一个不安全的查询进行简单选择时:

curs.execute("select name from people where sin = '1'")

结果是 'a',这正是我预期的。但是如果我使用绑定参数:

curs.execute("select name from people where sin = :v", v='1')

结果却是空的。我已经尝试将其改为位置参数 '?',并通过 setinputsizes(v=15) 设置 'v' 的大小,但似乎都没有效果。

我是不是漏掉了什么?

谢谢,

1 个回答

2

问题出在你使用了CHAR这种数据类型,而不是VARCHAR2。

在SQL*Plus中你可以看到这两者的区别。

如果我们绑定一个VARCHAR2变量,那么不会选中任何行:

SQL> variable v varchar2(15)
SQL> exec :v := '1';

PL/SQL procedure successfully completed.

SQL> select name from people where sin = :v;

no rows selected

但如果我们绑定一个CHAR变量,它和列的数据类型是一样的,那么就会选中一行:

SQL> variable v char(15)
SQL> exec :v := '1';

PL/SQL procedure successfully completed.

SQL> select name from people where sin = :v;

NAME
----------------------------------------
a

所以你要么需要把列的数据类型从CHAR改成VARCHAR2(顺便说一下,VARCHAR也已经过时了),要么就要告诉cx_Oracle使用FIXED_CHAR这种数据类型:

>>> v = curs.var(cx_Oracle.FIXED_CHAR, 15)
>>> v.setvalue(0, '1')
>>> print v
<cx_Oracle.FIXED_CHAR with value '1'>

>>> result = curs.execute("select name from people where sin = :sin", sin=v)
>>> for r in result: print r

('a',)

撰写回答