在setinputsizes()之后插入CLOB会引发非法变量名称/编号

时间:2015-06-01 13:33:49

标签: python oracle cx-oracle

我有一个oracle表,我试图从csv中插入大量数据(主要是长字符串)。

我发现我需要为我的字符串使用CLOB数据类型,因为它们通常超过4000个字符。我还发现我需要使用'setinputsizes()'函数或者遇到'ValueError:string data too'。

但不知何故,使用'setinputsizes()'会破坏我的插入查询,我得到'ORA-01036:非法变量名/号'?

示例:

create_query = "CREATE TABLE sequences (myid varchar(10), allele varchar(50), seq clob)"
cursor.execute (create_query)
cursor.setinputsizes(seq = cx_Oracle.CLOB)
insert_query = "INSERT INTO sequences (myid, allele, seq) VALUES ('00001;', 'HLA-A*01:01:01:01', 'CGCTGACCTGTG')" # seq truncated; in truth it's much longer hence the CLOB type
cursor.execute(insert_query)

没有'setinputsizes()'行,上面的查询执行正常 - 但是当我使用seq的实际值(超过4000个字符)时,它会失败

DatabaseError: ORA-01704: string literal too long

但是使用'setinputsizes()'行,我得到了

DatabaseError: ORA-01036: illegal variable name/number

(注意:我知道executemany对于批量插入更好。但我在那里遇到相同的错误,所以我首先尝试解决这个问题。)

谁能告诉我你做错了怎么解决? 谢谢!

3 个答案:

答案 0 :(得分:1)

使用超过4,000个字符(或字节)的字符串文字插入或更新CLOB时,需要将该字符串文字分配给PL / SQL变量,然后在PL /中插入或更新该表SQL块。

示例:

DECLARE
    l_seq CLOB;
BEGIN
    l_seq := 'CGCTGACCTGTG.....CGCTGACCTGTG';

    INSERT INTO sequences (myid, allele, seq) VALUES ('00001;', 'HLA-A*01:01:01:01', l_seq);
END;
/

答案 1 :(得分:0)

ORA-01704: string literal too long表示您发送到数据库的查询无法正确解析,因为有一些标识符太长。 该标识符可以是表名,列名,函数名(最大长度为30个字节)。

还要确保您的seq列没有转义问题(字符串中出现'且未转义。)

答案 2 :(得分:0)

DatabaseError: ORA-01036: illegal variable name/number的原因是对setinputsizes()的错误调用。

正确的行应

cursor.setinputsizes(None, None, cx_Oracle.CLOB)

因为setinputsizes()需要一次为所有绑定变量设置(按照正确的顺序!),而不是单独设置。

这需要与要输入的值的位置绑定相结合,否则就有DatabaseError: ORA-01036: illegal variable name/number

工作代码如下所示:

create_query = "CREATE TABLE sequences (myid varchar(10), allele varchar(50), seq clob)"
cursor.execute (create_query)
cursor.setinputsizes(None, None, cx_Oracle.CLOB)
insert_query = "INSERT INTO sequences (myid, allele, seq) VALUES (:1, :2, :3)" # seq truncated; in truth it's much longer hence the CLOB type
cursor.execute(insert_query, ['HLA00001;', 'HLA-A*01:01:01:01', seq])
conn.commit()