ORA-06533: PL/SQL 中的下标超出计数 ORA-06512

Posted

技术标签:

【中文标题】ORA-06533: PL/SQL 中的下标超出计数 ORA-06512【英文标题】:ORA-06533: Subscript beyond count ORA-06512 in PL/SQL 【发布时间】:2021-10-02 21:48:31 【问题描述】:

我想要 10 x 10 的网格,数字从 1 到 100 它给了我这个错误 ORA-06533: 下标超出计数 ORA-06512: 在第 25 行

ORA-06512:在“SYS.DBMS_SQL”,第 1721 行

我不明白这个错误,我无法解决它 有人可以帮我吗

DECLARE
    -- PL SQL code to create and fill a two-dimensional array
    -- create VARRAY type of 10 integers
    TYPE array_10_int  IS VARRAY(10) of PLS_INTEGER;

    -- create VARRAY type of array_10_int 
    TYPE grid_100_int IS VARRAY(10) of array_10_int;
    
    -- declare a variable of the grid_100_int type
    grid_var grid_100_int;
    
    -- declare counters 
    i PLS_INTEGER := 0;
    j PLS_INTEGER :=0;
    M PLS_INTEGER :=0;
    N PLS_INTEGER :=0;

BEGIN
    grid_var := grid_100_int();
    -- TO DO : use nested loop to fill grid_var with numbers 1- 100
    /** YOUR CODE HERE **/
    M:=0;
    Loop
        M:=M+1;
        N:=0;
        LOOP
           J:=j+1;
            If grid_var(M)(N)<100 THEN
               DBMS_OUTPUT.PUT(' ' || grid_var(M)(N) || ' ');
            ELSE
               DBMS_OUTPUT.PUT( grid_var(M)(N) || ' ');
            END IF;
            
            EXIT WHEN (N =100);
        END LOOP;
        dbms_output.put_line(' ');
        EXIT WHEN (M=10);
    END LOOP;
    

-- Print the grid with nested loop
    i:=0;
    LOOP --outer loop
        i := i+1;
        j := 0;
        LOOP    -- inner loop
            j:= j+1;
            IF grid_var(i)(j) < 10 THEN
                DBMS_OUTPUT.PUT(' ' || grid_var(i)(j) || ' ');
            ELSE
                DBMS_OUTPUT.PUT( grid_var(i)(j) || ' ');
            END IF;
           
            EXIT WHEN (j =10);
        END LOOP;
        dbms_output.put_line(' ');
        EXIT WHEN (i =10);
    END LOOP;    
    
    
END;

【问题讨论】:

这能回答你的问题吗? Creating or simulating two dimensional arrays in PL/SQL 您在第一个循环中使用j,但n 保持不变。代码应该永远运行 【参考方案1】:

再看一遍。 创建多维数组 (10 x 10) 是一件棘手的事情。它们实际上是一个集合的集合。此外,每个元素都有相同的定义和存在要求:元素必须在引用之前存在,extendarray initialization。下面在引用它之前初始化每个数组。它还使用FOR loop 让 Postgres 处理设置、递增下标和循环退出,而不是手动处理。见demo。

declare
    -- PL SQL code to create and fill a two-dimensional array
    -- create VARRAY type of 10 integers
    type array_10_int  is varray(10) of pls_integer;  

    -- create VARRAY type of array_10_int 
    type grid_100_int is varray(10) of array_10_int ;  
    
    -- declare a variable of the grid_100_int type
    grid_var grid_100_int;
begin

    grid_var := grid_100_int(null,null,null,null,null,null,null,null,null,null);  -- initialize outer array 
    -- TO DO : use nested loop to fill grid_var with numbers 1- 100
    /* YOUR CODE HERE */
    
    for m in 1 .. 10 
    loop 
        grid_var(m) := array_10_int(null,null,null,null,null,null,null,null,null,null); -- initialize the inner array   
        for n in 1 .. 10 
        loop                                  
            grid_var(m)(n) := 10*(m-1)+ n;   
        end loop ; 
    end loop; 
 
-- Print the grid with nested loop
      for m in 1 .. 10 
      loop
         for n in 1 .. 10 
         loop 
            dbms_output.put_line ('grid_var(' || to_char(m) 
                                 || ')(' || to_char(n) 
                                 || ') = ' || to_char(grid_var(m)(n))
                                 );    
        end loop ;   
    end loop; 
    
end;

带走: 在 Oracle 中创建和使用多维数组是可行的。 But use them only when there is no other option. 它们增加了相当大的复杂性,通常是不必要的,而且人们对此知之甚少。 (上面的很简单。)带走 2 让 Postgres 控制您的循环。更不容易出错,更少的代码,更容易阅读。


PL/SQL 数组索引以 1 开头。但在以下代码中,局部变量 n 在首次用作索引时为 0。

 Loop
        M:=M+1;
        N:=0;
        LOOP
           J:=j+1;
            If grid_var(M)(N)<100 THEN    --<<< n is 0 which throws your  exception.
                ... 
               EXIT WHEN (N =100);   --<<< NEVER occurs, N is not  

不幸的是,这不是您唯一的问题(在此逻辑中)。你退出语句是条件EXIT WHEN (N =100); 永远不会被满足。在进入循环之前初始化变量n,但不要在循环中增加它。 将上述调整为:

    Loop
                M:=M+1;
                N:=1;          -- <<< change here 
                LOOP
                   J:=j+1;
                    If grid_var(M)(N)<=100 THEN 
                    ... 
                   EXIT WHEN (N >100);   --<<< NEVER occurs, N is not incremented in the loop;
                END LOOP;  

您的另一个循环似乎没有同样的问题,但您应该检查一下。

【讨论】:

以上是关于ORA-06533: PL/SQL 中的下标超出计数 ORA-06512的主要内容,如果未能解决你的问题,请参考以下文章

c++和opencv中的向量下标超出范围错误

在 SwiftUI 中符合 RandomAccessCollection 时,下标中的索引超出范围

调试错误 - 向量下标超出范围 - PCL

访问 std::string 中的空终止字符(字符串下标超出范围)

SQL记录-PLSQL面向对象

PL/SQL数据开发那点事