获取错误cx_oracle.databaseerror:ora-01008:在合并语句中尝试绑定列表的值时,并非所有变量绑定
我从最近几个小时开始敲打头,但找不到根本原因。经历了多篇文章,但没有运气。
我正在尝试合并熊猫数据框架中存储的值。 以下是我通过下面代码将数据范围转换为列表的代码,
merchantinfo_lst = appenddata.values.tolist()
我试图将数据合并到目标表中。
sql ='merge into bi.merchant_info_test ';
sql+=' using dual';
sql+=' on ( ATRANS_ID = :2 )';
sql+=' when matched then update set MERCHANT_INFO = :15, MESSAGE_PARAM = :16, PUBLISH_DATE = :13' ;
sql+=' when not matched then insert( ADDRESS,ATRANS_ID,CITY_NAME,COUNTRY_CODE,LATITUDE,LONGITUDE,MERCHANT_CATEGORY_CODE,MERCHANT_DESCRIPTOR,MERCHANT_ID,';
sql+=' MERCHANT_NAME,PHONE_NUMBER,POSTAL_CODE,PUBLISH_DATE,STATE_PROVINCE_CODE,MERCHANT_INFO,MESSAGE_PARAM )';
sql+=' values( :1, :2, :3,:4,:5,:6,:7,:8,:9,:10,:11,:12,:13,:14,:15,:16 )';
for i in range(len(merchantinfo_lst)):
cur.execute(sql,merchantinfo_lst[i])
我将获得cx_oracle.databaseerror:ora-01008:并非所有变量绑定,但所有值都存在于列表中,所有列都存在于目标表中。 无论我尝试什么,我都无法解决问题。
Python版本:2.7.5 cx_oracle版本:7.3.0 目标数据库:Oracle数据库19C Enterprise Edition版本19.0.0.0.0
表结构
Name Null? Type
---------------------- -------- --------------
ATRANS_ID NOT NULL RAW(36 BYTE)
MERCHANT_ID VARCHAR2(20)
MERCHANT_DESCRIPTOR VARCHAR2(100)
MERCHANT_NAME VARCHAR2(100)
ADDRESS VARCHAR2(250)
CITY_NAME VARCHAR2(100)
STATE_PROVINCE_CODE VARCHAR2(4)
POSTAL_CODE VARCHAR2(10)
COUNTRY_CODE VARCHAR2(10)
LATITUDE VARCHAR2(20)
LONGITUDE VARCHAR2(20)
PHONE_NUMBER VARCHAR2(15)
MERCHANT_CATEGORY_CODE VARCHAR2(6)
MERCHANT_INFO VARCHAR2(250)
MESSAGE_PARAM VARCHAR2(2000)
PUBLISH_DATE DATE
Python代码
def table_merge(data_frame,uname,passwd,oracle_dsn):
merchantinfo = pd.DataFrame()
transidinfo = pd.DataFrame()
ora_con = oracle_conn(uname,passwd,oracle_dsn)
cur = ora_con.cursor()
now = datetime.now()
dt_string = now.strftime("%d/%m/%Y %H:%M:%S")
appenddata['MERCHANT_INFO'] = appenddata['MERCHANT_NAME']+ ' ' +appenddata['CITY_NAME']+ ' '+appenddata['STATE_PROVINCE_CODE']+ ' ' +appenddata['COUNTRY_CODE']+ ' ' +appenddata['POSTAL_CODE']
appenddata['MESSAGE_PARAM'] = appenddata['MERCHANT_ID']+ '|' + appenddata['MERCHANT_INFO']
appenddata['PUBLISH_DATE'] = dt_string
merchantinfo_lst = appenddata.values.tolist()
print('printing list')
print(merchantinfo_lst)
sql ='merge into bi.merchant_info_test ';
sql+=' using dual';
sql+=' on ( ATRANS_ID = :2 )';
sql+=' when matched then update set MERCHANT_INFO = :15, MESSAGE_PARAM = :16, PUBLISH_DATE = :13' ;
sql+=' when not matched then insert( ADDRESS,ATRANS_ID,CITY_NAME,COUNTRY_CODE,LATITUDE,LONGITUDE,MERCHANT_CATEGORY_CODE,MERCHANT_DESCRIPTOR,MERCHANT_ID,';
sql+=' MERCHANT_NAME,PHONE_NUMBER,POSTAL_CODE,PUBLISH_DATE,STATE_PROVINCE_CODE,MERCHANT_INFO,MESSAGE_PARAM )';
sql+=' values( :1, :2, :3,:4,:5,:6,:7,:8,:9,:10,:11,:12,:13,:14,:15,:16 )';
for i in range(len(merchantinfo_lst)):
cur.execute(sql,merchantinfo_lst[i])
cur.close()
ora_con.commit()
ora_con.close()
输出
/home/kkant/microservice-poc % python consumer.py
printing list
[[u'dummy_address', u'123456789', u'dummy_city', u'91', u'', u'', u'2345', u'dummy', u'123', u'dummy_merchant', u'1234567890', u'123456', '27/05/2022 11:32:22', u'', u'dummy_merchant dummy_city 91 123456', u'123|dummy_merchant dummy_city 91 123456'], [u'dummy_address', u'1234567455', u'dummy_city', u'91', u'', u'', u'2345', u'dummy', u'456', u'dummy_merchant', u'1234567890', u'123456', '27/05/2022 11:32:22', u'', u'dummy_merchant dummy_city 91 123456', u'456|dummy_merchant dummy_city 91 123456']]
Traceback (most recent call last):
File "consumer.py", line 102, in <module>
table_merge(appenddata)
File "consumer.py", line 71, in table_merge
cur.execute(sql,merchantinfo_lst[i])
cx_Oracle.DatabaseError: ORA-01008: not all variables bound
[enter image description here][1]
I am banging my head from last few hours but unable to find the root cause. went through multiple articles but no luck.
I am trying to merge the values which are stored inside a pandas dataframe.
Below is the code where I am converting the dataframe into list
merchantinfo_lst = appenddata.values.tolist()
Through below code I am trying to merge data into the target table.
sql ='merge into bi.merchant_info_test ';
sql+=' using dual';
sql+=' on ( ATRANS_ID = :2 )';
sql+=' when matched then update set MERCHANT_INFO = :15, MESSAGE_PARAM = :16, PUBLISH_DATE = :13' ;
sql+=' when not matched then insert( ADDRESS,ATRANS_ID,CITY_NAME,COUNTRY_CODE,LATITUDE,LONGITUDE,MERCHANT_CATEGORY_CODE,MERCHANT_DESCRIPTOR,MERCHANT_ID,';
sql+=' MERCHANT_NAME,PHONE_NUMBER,POSTAL_CODE,PUBLISH_DATE,STATE_PROVINCE_CODE,MERCHANT_INFO,MESSAGE_PARAM )';
sql+=' values( :1, :2, :3,:4,:5,:6,:7,:8,:9,:10,:11,:12,:13,:14,:15,:16 )';
for i in range(len(merchantinfo_lst)):
cur.execute(sql,merchantinfo_lst[i])
I am getting cx_Oracle.DatabaseError: ORA-01008: not all variables bound but all the value are present in the list and all the column are present in the target table.
No matter what I try, I am not able to resolve the issue.
Python version: 2.7.5
cx_Oracle version: 7.3.0
Target database : Oracle Database 19c Enterprise Edition Release 19.0.0.0.0
Table structure
Name Null? Type
---------------------- -------- --------------
ATRANS_ID NOT NULL RAW(36 BYTE)
MERCHANT_ID VARCHAR2(20)
MERCHANT_DESCRIPTOR VARCHAR2(100)
MERCHANT_NAME VARCHAR2(100)
ADDRESS VARCHAR2(250)
CITY_NAME VARCHAR2(100)
STATE_PROVINCE_CODE VARCHAR2(4)
POSTAL_CODE VARCHAR2(10)
COUNTRY_CODE VARCHAR2(10)
LATITUDE VARCHAR2(20)
LONGITUDE VARCHAR2(20)
PHONE_NUMBER VARCHAR2(15)
MERCHANT_CATEGORY_CODE VARCHAR2(6)
MERCHANT_INFO VARCHAR2(250)
MESSAGE_PARAM VARCHAR2(2000)
PUBLISH_DATE DATE
Python code
def table_merge(data_frame,uname,passwd,oracle_dsn):
merchantinfo = pd.DataFrame()
transidinfo = pd.DataFrame()
ora_con = oracle_conn(uname,passwd,oracle_dsn)
cur = ora_con.cursor()
now = datetime.now()
dt_string = now.strftime("%d/%m/%Y %H:%M:%S")
appenddata['MERCHANT_INFO'] = appenddata['MERCHANT_NAME']+ ' ' +appenddata['CITY_NAME']+ ' '+appenddata['STATE_PROVINCE_CODE']+ ' ' +appenddata['COUNTRY_CODE']+ ' ' +appenddata['POSTAL_CODE']
appenddata['MESSAGE_PARAM'] = appenddata['MERCHANT_ID']+ '|' + appenddata['MERCHANT_INFO']
appenddata['PUBLISH_DATE'] = dt_string
merchantinfo_lst = appenddata.values.tolist()
print('printing list')
print(merchantinfo_lst)
sql ='merge into bi.merchant_info_test ';
sql+=' using dual';
sql+=' on ( ATRANS_ID = :2 )';
sql+=' when matched then update set MERCHANT_INFO = :15, MESSAGE_PARAM = :16, PUBLISH_DATE = :13' ;
sql+=' when not matched then insert( ADDRESS,ATRANS_ID,CITY_NAME,COUNTRY_CODE,LATITUDE,LONGITUDE,MERCHANT_CATEGORY_CODE,MERCHANT_DESCRIPTOR,MERCHANT_ID,';
sql+=' MERCHANT_NAME,PHONE_NUMBER,POSTAL_CODE,PUBLISH_DATE,STATE_PROVINCE_CODE,MERCHANT_INFO,MESSAGE_PARAM )';
sql+=' values( :1, :2, :3,:4,:5,:6,:7,:8,:9,:10,:11,:12,:13,:14,:15,:16 )';
for i in range(len(merchantinfo_lst)):
cur.execute(sql,merchantinfo_lst[i])
cur.close()
ora_con.commit()
ora_con.close()
Output
/home/kkant/microservice-poc % python consumer.py
printing list
[[u'dummy_address', u'123456789', u'dummy_city', u'91', u'', u'', u'2345', u'dummy', u'123', u'dummy_merchant', u'1234567890', u'123456', '27/05/2022 11:32:22', u'', u'dummy_merchant dummy_city 91 123456', u'123|dummy_merchant dummy_city 91 123456'], [u'dummy_address', u'1234567455', u'dummy_city', u'91', u'', u'', u'2345', u'dummy', u'456', u'dummy_merchant', u'1234567890', u'123456', '27/05/2022 11:32:22', u'', u'dummy_merchant dummy_city 91 123456', u'456|dummy_merchant dummy_city 91 123456']]
Traceback (most recent call last):
File "consumer.py", line 102, in <module>
table_merge(appenddata)
File "consumer.py", line 71, in table_merge
cur.execute(sql,merchantinfo_lst[i])
cx_Oracle.DatabaseError: ORA-01008: not all variables bound
[enter image description here][1]
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
问题在于您是按位置绑定的,而不是按名称绑定。因此,您需要每个绑定变量位置的条目。值:2在您的SQL语句的第一部分中需要一个值和值:2在您的SQL语句的最后一部分中也需要一个值! (有关SQL语句中提到的每个绑定变量的依此类推 - 其中20个)。如果您不想这样做,则可以通过名称绑定(并提供参数字典)。
可能有效的另一种可能性是执行所有参数的“查询”,例如:
这样,您只有一个地方需要绑定变量而不是两个(对于其中的某些)。
几天前发布的新的Python驱动程序(Python-OracleDB)在使用薄模式时会对这种事情有更好的错误消息(请参阅文档有关更多详细信息)。可能值得尝试与该驱动程序的示例来找出问题的根源。
附带说明,最好在插入多行时使用opecutemany(),而不是在列表中迭代并重复调用execute()。性能的差异可能会引人注目,尤其是对于大量行!
The problem is that you are binding by position, not by name. So you need an entry for every bind variable position. The value :2 in the first part of your SQL statement needs a value and the value :2 in the last part of your SQL statement also needs a value! (And so on for every bind variable mentioned in your SQL statement -- 20 of them). If you don't want to do that you can bind by name instead (and supply a dictionary of parameters).
One other possibility that may work is to perform a "query" of all of the parameters, as in this:
That way you only have one place where the bind variables are required instead of two (for some of them).
The new Python driver released a couple of days ago (python-oracledb) has better error messages for this sort of thing when using thin mode (see the documentation for more details). It may be worth trying your example with that driver to find out the source of the issue.
On a side note, it is better to use executemany() when inserting multiple rows instead of iterating through the list and calling execute() repeatedly. The difference in performance can be striking, especially for large numbers of rows!