如何在 forall 循环中将索引转换为整数?

How to transform the index in a integer in a forall loop?

CREATE TYPE o_A AS OBJECT (A1 VARCHAR2 (4000));

CREATE OR REPLACE TYPE t_A IS TABLE OF o_A;

CREATE TABLE table_o_A
(
      oA_id                INTEGER GENERATED BY DEFAULT AS IDENTITY,
      oA                   o_A,
      PRIMARY KEY (oA_id)
    );

我想在 table_oA 中添加 t_A 行。

CREATE PROCEDURE aa (query_result    t_A)
is
    v_i   INTEGER;
begin
    SELECT MAX (oA_id)
          INTO v_i
          FROM table_o_A;
          
    FORALL i IN INDICES OF query_result
            INSERT INTO table_o_A(
                            oA_id,
                            oA)
                 VALUES ( v_i+i, query_result (i));
                 
end;

[Error] Compilation (887: 26): PLS-00430: FORALL iteration variable I is not allowed in this context

我认为它不起作用,因为 i 不是整数。 我可以使用 for 循环并使用实数,但它会在 pl/sql 和 sql 上下文之间进行切换。 我如何使用 ForAll 循环做到这一点?

code

solution from Alex Poole

I thinks it doesn't work because i isn't an integer.

不,这是对forall语法的限制; from the documentation,您的 i 索引是(强调):

Name for the implicitly declared integer variable that is local to the FORALL statement. Statements outside the FORALL statement cannot reference index. Statements inside the FORALL statement can reference index as an index variable, but cannot use it in expressions or change its value. After the FORALL statement runs, index is undefined.


您的 oA_id 是一个 sequence-backed 标识列 - 虽然只是默认值,但并非总是如此 - 因此您不必指定值。除非您已经在混合手动和 auto-assigned ID 值,否则您获得的最大值将与序列值兼容(当然可能存在差距);但是手动设置 ID 值后,序列将失调,并且您会与 auto-assigned 值发生冲突,除非它被重置为当前限制。

除非你有充分的理由混合使用手动和自动,否则你可以简化你正在做的事情:

CREATE PROCEDURE a (query_result    t_A)
is
begin
    FORALL i IN INDICES OF query_result
            INSERT INTO table_o_A(oA)
                 VALUES (query_result (i));
end;
/

...和提供插入语句中的对象。

db<>fiddle