简体   繁体   English

PL/SQL:当我尝试调用 sql%bulk_rowcount(j) 时,我得到“必须声明标识符 j”;

[英]PL/SQL: I get "Identifier j must be declared'" when I try to call sql%bulk_rowcount(j);

My code:我的代码:

create table dep_emp_ast(
cod_dep number(3),
cod_ang number(3));

declare
type tab_imb is table of dept_ast.department_id%type;
type ang is table of emp_ast.employee_id%type;
v_ang ang:=ang();
t tab_imb:=tab_imb();
begin
select department_id
bulk collect into t
from dept_ast;

for i in 1..t.count loop
select employee_id bulk collect into v_ang
from emp_ast
where department_id=t(i);

forall j in 1..v_ang.count
insert into dep_emp_ast
values(t(i), v_ang(j));
dbms_output.put_line( sql%bulk_rowcount(j));
v_ang.delete;
end loop;
end;
/

I get "Identifier 'j' must be declared'" when I try to call sql%bulk_rowcount(j);当我尝试调用 sql%bulk_rowcount(j) 时出现“必须声明标识符‘j’”; I know I can use sql%bulk_rowcount(index) in for or forall loops.我知道我可以在 for 或 forall 循环中使用 sql%bulk_rowcount(index)。

Here's a working version.这是一个工作版本。

I renamed some variables to be easier to understand (for me at least), and I added some more dbms_output messages to show what it's doing more clearly.我重命名了一些变量以便更容易理解(至少对我而言),并且我添加了更多dbms_output消息以更清楚地显示它在做什么。

declare
    type tab_dept is table of dept_ast.department_id%type;
    type tab_emp  is table of emp_ast.employee_id%type;
    employees_t    tab_emp := tab_emp();
    departments_t  tab_dept := tab_dept();
begin
    select department_id bulk collect into departments_t
    from   dept_ast;

    dbms_output.put_line(departments_t.count || ' departments added to departments_t');

    for i in 1 .. departments_t.count loop
        select employee_id bulk collect into employees_t
        from   emp_ast where department_id = departments_t(i);

        dbms_output.put_line(employees_t.count || ' employees added to employees_t for department_id '||departments_t(i));

        forall j in 1 .. employees_t.count
        insert into dep_emp_ast
        values
        ( departments_t(i)
        , employees_t(j) );

        for k in 1 .. employees_t.count loop
            dbms_output.put_line('sql%bulk_rowcount('||k||') = '|| sql%bulk_rowcount(k));
        end loop;

        dbms_output.put_line('sql%rowcount = ' ||sql%rowcount);
        employees_t.delete;
    end loop;
end;

Output: Output:

3 departments added to departments_t
2 employees added to employees_t for department_id 1
sql%bulk_rowcount(1) = 1
sql%bulk_rowcount(2) = 1
sql%rowcount = 2
2 employees added to employees_t for department_id 2
sql%bulk_rowcount(1) = 1
sql%bulk_rowcount(2) = 1
sql%rowcount = 2
2 employees added to employees_t for department_id 3
sql%bulk_rowcount(1) = 1
sql%bulk_rowcount(2) = 1
sql%rowcount = 2

Test setup:测试设置:

create table dep_emp_ast(
cod_dep number(3),
cod_ang number(3));

create table dept_ast
( department_id number );

create table emp_ast
( employee_id number 
, department_id number );

delete dept_ast;
delete emp_ast;

insert all
    into dept_ast values (1)
    into dept_ast values (2)
    into dept_ast values (3)
    into emp_ast (department_id, employee_id) values (1, 10)
    into emp_ast (department_id, employee_id) values (1, 20)
    into emp_ast (department_id, employee_id) values (2, 30)
    into emp_ast (department_id, employee_id) values (2, 40)
    into emp_ast (department_id, employee_id) values (3, 50)
    into emp_ast (department_id, employee_id) values (3, 60)
select * from dual;

@WilliamRobertson is correct in his comment that "you haven't declared j anywhere" and I take his word that it is a working version. @WilliamRobertson 在他的评论中是正确的,“你没有在任何地方声明 j”,我相信他的话,这是一个工作版本。 But neither actually explains why you get the error.但两者都没有真正解释为什么会出现错误。 Your code actually shows 2 misconceptions.您的代码实际上显示了 2 个误解。
First the initialization (for lack of a better work) of FOR and FORALL is首先 FOR 和 FORALL 的初始化(因为缺乏更好的工作)是

FOR <index> IN <lower bound> .. <upperbound> Loop ... END LOOP; 
FORALL <index> IN <lower bound> .. <upperbound> DML statement;

In both cases the variable is created for the duration of the statement only .在这两种情况下,变量仅在语句执行期间创建。 Thus when the loop or the DML statement terminates the variable no longer exists.因此当循环或 DML 语句终止时变量不再存在。 Thus when you used the variable j after the insert ended it no longer existed.因此,当您在插入结束后使用变量 j 时,它不再存在。 Even if you do declare a variable with the same name the scoping rules cause them to be different variables (see example here ).即使您确实声明了一个具有相同名称的变量,范围规则也会导致它们成为不同的变量(请参见此处的示例)。
You have another issue as well.你还有另一个问题。 SQL%bulk_rowcount contains as entry for each row row processed, but since the index variable of the forall no longer exists you need a FOR loop to iterate them. SQL%bulk_rowcount 包含处理的每一行行的条目,但由于 forall 的索引变量不再存在,您需要一个 FOR 循环来迭代它们。 So, after the forall:所以,在forall之后:

for j in 1..v_ang.count
loop
    dbms_output.put_line( ' Rows for ' || v_ang(j) || ':' || SQL%bulk_rowcount(j));
end loop;

But assuming v_ang contains the PK for employee table (seems likely) that will just five you a list of 1. Perhaps you actually want SQL%Rowcount.但假设 v_ang 包含员工表的 PK(似乎很可能),那将只有五个你的列表 1。也许你真的想要 SQL%Rowcount。 That gives you the total number of rows processed.这为您提供了处理的总行数。

I hope this helps you to understand for(all) loop index variables.我希望这可以帮助您理解 for(all) 循环索引变量。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM