Insert next value of sequence using cx_Oracle Cursor.executemany()
我正在尝试在python中使用cx_oracle库插入行,其中列值之一是称为an_aj_s的序列中的下一个值。
我已经创建了一个函数来执行此操作,称为insert_into_columns,对该函数的调用如下所示:
1 2 3 | self.insert_into_columns('AN_JOB', ('AJ_ID','AJ_JOBNAME', 'AJ_DESCRIPTION', 'AJ_CD_JOB_TYPE', 'AJ_CD_DATABASE','AJ_CD_JOB_STATUS', 'AJ_USR_ID', 'AJ_CREATE_DATE', 'AJ_EQUIP_COMPS_FLAG'), [ ('an_aj_s.nextval', 'QlikManual_3', 'First Manually entered Test Job', 2, 0, 1 ,6 , dt.today().date(), 1)]) |
其中的参数是:
当我调用该函数时,我得到一个错误的无效数字:
cx_Oracle.DatabaseError:ORA-01722:无效的数字
我确定问题出在序列上,因为如果我用数字替换序列,则插入成功。有人可以告诉我在表中插入行时如何调用序列吗?
我尝试使用cur.setinputsizes()设置输入大小,但似乎不起作用。
其他信息:
我的函数生成的SQL语句如下所示:
1 | INSERT INTO AN_JOB (AJ_ID,AJ_JOBNAME,AJ_DESCRIPTION,AJ_CD_JOB_TYPE,AJ_CD_DATABASE,AJ_CD_JOB_STATUS,AJ_USR_ID,AJ_CREATE_DATE,AJ_EQUIP_COMPS_FLAG) VALUES ( :1, :2, :3, :4, :5, :6, :7, :8, :9 ) |
生成语句的实际python函数如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | def insert_into_columns(self, table_name, columns, rows): sql ="INSERT INTO {table_name} ({column_names}) VALUES ({column_args} )" args_str = '' col_str = '' for col_id in range(1, len(columns) + 1): args_str += ' :' + str(col_id) col_str += columns[col_id - 1] if col_id < len(columns): args_str += ',' col_str += ',' sql = sql.format(table_name=table_name, column_names =col_str, column_args=args_str) print('Inserting rows into specified columns...') print(sql) with self.conn.cursor() as cur: cur.executemany(sql, rows) self.conn.commit() |
在您的SQL语句中,您正在将所有值作为绑定变量传递。通常很棒!但是绑定变量不会由SQL引擎解释。因此,对于
您需要修改您的功能,以代替此内容:
1 2 | INSERT INTO AN_JOB (AJ_ID,AJ_JOBNAME,AJ_DESCRIPTION,AJ_CD_JOB_TYPE,AJ_CD_DATABASE,AJ_CD_JOB_STATUS,AJ_USR_ID,AJ_CREATE_DATE,AJ_EQUIP_COMPS_FLAG) VALUES ( :1, :2, :3, :4, :5, :6, :7, :8, :9 ) |
您正在生成此内容:
1 2 | INSERT INTO AN_JOB (AJ_ID,AJ_JOBNAME,AJ_DESCRIPTION,AJ_CD_JOB_TYPE,AJ_CD_DATABASE,AJ_CD_JOB_STATUS,AJ_USR_ID,AJ_CREATE_DATE,AJ_EQUIP_COMPS_FLAG) VALUES ( an_aj_s.nextval, :2, :3, :4, :5, :6, :7, :8, :9 ) |
这有意义吗?您可以通过多种方法来更改功能以实现此目的,但是您没有解释其他用例,因此我不想提出任何特定的用例。
或者,您可能会发现通过创建序列触发器在Oracle方面更容易做到这一点。 SO上有很多示例(像这样)
1 2 3 4 5 6 7 8 | CREATE OR REPLACE TRIGGER an_job_id_trigger BEFORE INSERT ON an_job FOR EACH ROW WHEN (new.ID IS NULL) BEGIN :new.ID := an_aj_s.nextval; END; / |
这样,您可以将插入中的
1 2 | INSERT INTO AN_JOB (AJ_JOBNAME,AJ_DESCRIPTION,AJ_CD_JOB_TYPE,AJ_CD_DATABASE,AJ_CD_JOB_STATUS,AJ_USR_ID,AJ_CREATE_DATE,AJ_EQUIP_COMPS_FLAG) VALUES (:1, :2, :3, :4, :5, :6, :7, :8 ) |