在过go 的几个小时里,我一直在头痛,但找不到根本原因.浏览了多篇文章,但运气不佳.

我正在try 合并存储在Pandas 数据框中的值.

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\U Oracle.DatabaseError:ORA-01008:并非所有变量都已绑定,但列表中存在所有值,目标表中存在所有列.

Python版本:2.7.5

表 struct

    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]

推荐答案

问题是您是按位置绑定的,而不是按名称绑定的.因此,每个绑定变量位置都需要一个条目.SQL语句第一部分的值:2需要一个值,SQL语句最后部分的值:2也需要一个值!(对于SQL语句中提到的每个bind变量,依此类推——其中20个).如果不想这样做,可以改为按名称绑定(并提供一个参数字典).

另一种可行的方法是对所有参数执行"查询",如下所示:

merge into bi.merchant_info_test target
using select :1 as x, :2, as y, :3 as z, ... from dual source
on target.atrans_id = source.atrans_id
when matched then update set merchant_info = source.merchant_info ...
when not matched then insert (ADDRESS, ...) values (source.address, ...)

这样,您就只需要一个地方需要绑定变量,而不是两个(对于其中一些).

几天前发布的新Python驱动程序(Python oracledb)在使用精简模式时有更好的错误消息(有关更多详细信息,请参阅documentation).也许有必要用这个驱动程序来try 你的例子,以找出问题的根源.

另一方面,插入多行时最好使用executemany(),而不是遍历列表并重复调用execute().性能上的差异可能非常显著,尤其是对于大量的行!

Python相关问答推荐

将从Python接收的原始字节图像数据转换为C++ Qt QIcon以显示在QStandardProject中

具有2D功能的Python十六进制图

Python panda拆分列保持连续多行

在Pandas框架中截短至固定数量的列

根据给定日期的状态过滤查询集

理解Python的二分库:澄清bisect_left的使用

如何在图片中找到这个化学测试条?OpenCV精明边缘检测不会绘制边界框

Select 用a和i标签包裹的复选框?

pandas DataFrame GroupBy.diff函数的意外输出

试图找到Python方法来部分填充numpy数组

根据另一列中的nan重置值后重新加权Pandas列

将jit与numpy linSpace函数一起使用时出错

使用miniconda创建环境的问题

不理解Value错误:在Python中使用迭代对象设置时必须具有相等的len键和值

管道冻结和管道卸载

如何在Python中并行化以下搜索?

基于字符串匹配条件合并两个帧

为什么NumPy的向量化计算在将向量存储为类属性时较慢?'

在Python中使用if else或使用regex将二进制数据如111转换为001""

为罕见情况下的回退None值键入