带有executemany和部分参数化列表的插入

lokaqttq  于 2021-08-09  发布在  Java
关注(0)|答案(2)|浏览(302)

我正在尝试改进一个将元素插入到oracle数据库中的批处理服务。目前我在插入过程中有性能问题。
现在我的插入字符串是这样的:

INSERT INTO MYTABLE (COL1, COL2, COL3) VALUES (:COL1, :COL2, :COL3);

而字符串的执行类似于:

with connection.cursor() as cursor:
    cursor.executemany(sql, list)

在这之前没什么不寻常的对吧?!
但是mytable有一个pk列,它由insert执行时的触发器(从序列表中找出pk)填充。注意,我将有几个并行进程执行相同的插入,每个进程都访问触发器,从而访问序列表。
从我最初的研究中,我发现我可以直接在insert中删除触发器并访问sequence表,这是我的问题,我如何编写这个insert字符串?
像这样的事情是行不通的:

INSERT INTO MYTABLE (ID, COL1, COL2, COL3) VALUES (MYTABLE_SQ.nextval, :COL1, :COL2, :COL3);

这也不是(即使列的设置顺序正确):

INSERT INTO MYTABLE VALUES (MYTABLE_SQ.nextval, :COL1, :COL2, :COL3);

有什么想法吗?

f0ofjuux

f0ofjuux1#

直接访问序列表
首先,您需要创建 SEQUENCE 对象直接引用它以获取 NEXTVAL 价值观。您不能像您在问题中提到的那样从序列表中获取它。您可以使用序列自动递增,而不是将其存储在表中并获取它。为了 Pre 12c versions ,的 SEQUENCE +TRIGGER 是正确的方法。
我不知道为什么你决定在第一时间删除触发器并尝试访问sql中的序列。因为,你的方法引入了另一个问题,你正在尝试这样做:

INSERT INTO table(col1, col2, col2, col3)
VALUES (sequence_name.NEXTVAL, :2, :3, :4)

而不是:

INSERT INTO table(id, col1, col2, col3)
VALUES (:1, :2, :3, :4)

区别在于,不是bind变量 :name 你路过了 sequence_name.NEXTVAL . 为了避免这种情况,您可以这样做:

cursor.execute("select sequence_name.NEXTVAL from dual")
seq_value, = cursor.fetchone() --> assign sequence value then pass as bind variable

INSERT INTO table(id, col2, col3, col4)
VALUES (:seq_value, :2, :3, :4)

为了避免所有这些与序列相关的维护,如果您在 Oracle 12c 请使用 IDENTITY COLUMN . 有关标识列,请参见oracle文档。

j1dl9f46

j1dl9f462#

以下是关键:

DECLARE
    ID NUMBER := MYTABLE_SQ.nextval;
BEGIN
    INSERT INTO MYTABLE (ID, COL1, COL2, COL3) VALUES (ID, COL1, COL2, COL3);
END;

相关问题