首页 > 解决方案 > PL-SQL:返回错误 - 将元素插入(用户输入)索引并将所有元素移动到元素 [i+1]

问题描述

TYPE arr is VARRAY(10) of VARCHAR(32);
ar arr := arr('1', '1', '1');
idx INTEGER(100);
tmp INTEGER(100);
val VARCHAR(32);

PROCEDURE APPENDARR (arr IN OUT arr, idx IN, val IN) IS

BEGIN
    if(idx > arr.LIMIT) then
    tmp := (idx - arr.LIMIT);
    arr.extend(tmp);

    FOR i in REVERSE idx..arr.LAST LOOP
    arr(i) := arr(i - 1);
    if(arr(i) = arr(idx)) THEN
    arr(i) := val;
    END IF;
    END LOOP;
    ELSE
    arr.extend();
    arr(idx) := val;
    END IF;


END; 

错误代码:ORA-06550:第 10 行,第 48 列:PLS-00103:遇到符号“,”时预期以下情况之一:

out long double ref char 时间 时间戳 间隔 日期 二进制 国家字符 nchar

谁能帮我解决我的错误?抱歉英语不是我的母语,但我尽力了:)!

标签: sqloracleplsql

解决方案


我猜这是一个包的一部分,否则你需要create or replace语法。出于演示目的,我将它放在一个匿名块中只是为了测试编译。

两个问题:

  1. integer不需要精确,它只是integer.
  2. idx参数val缺少数据类型。

以下编译(我没有检查它的作用或是否有更好的实现):

declare
    type arr is varray(10) of varchar(32);
    ar  arr := arr('1', '1', '1');
    idx integer;
    tmp integer;
    val varchar(32);

    procedure appendarr
        ( arr in out arr
        , idx in integer
        , val in varchar2 )
    is
    begin
        if idx > arr.limit then
            tmp := idx - arr.limit;
            arr.extend(tmp);
        
            for i in reverse idx .. arr.last loop
                arr(i) := arr(i - 1);

                if arr(i) = arr(idx) then
                    arr(i) := val;
                end if;
            end loop;
        else
            arr.extend();
            arr(idx) := val;
        end if;
    
    end;
begin
    null;
end;

PL/SQLif条件由then关键字终止,因此它们不需要像其他语言那样的括号,所以我删除了它们。

此外,您有 variables idxtmpval在顶部声明了它们没有在任何地方使用,并且它们也与过程中的局部变量具有相同的名称,这可能会造成混淆。如果没有更多的代码你没有展示使用它们,也许你可以摆脱它们。

编辑:根据要求,这是一个独立程序的样子:

create or replace type arr as varray(10) of varchar(32)
/
create or replace procedure appendarr
    ( arr in out arr
    , idx in integer
    , val in varchar2 )
as
    tmp integer;
begin
    if idx > arr.limit then
        tmp := idx - arr.limit;
        arr.extend(tmp);

        for i in reverse idx .. arr.last loop
            arr(i) := arr(i - 1);
            if arr(i) = arr(idx) then
                arr(i) := val;
            end if;
        end loop;
    else
        arr.extend();
        arr(idx) := val;
    end if;
    
end appendarr;
/

/某些开发工具需要该字符来分隔块,但它不是 PL/SQL 语言本身的一部分。)

似乎目的是将值插入到数组val元素中,将现有值向上移动一个位置。但是,它并不完全有效:idxarr

declare
    ar  arr := arr('First', 'Second');
begin
    appendarr
    ( arr => ar
    , idx => 2
    , val => 'New value' );

    for i in ar.first..ar.last loop
        dbms_output.put_line(i||' '||ar(i));
    end loop;
end;
1 First
2 New value
3 

固定版本:

create or replace type varchar2_tt as table of varchar2(50)
/
create or replace procedure varchar2_tt_append
    ( arr in out varchar2_tt
    , pos in pls_integer default null
    , val in varchar2 )
as
    idx pls_integer := nvl(pos,arr.last +1);
begin
    if idx > arr.last then
        arr.extend(idx - arr.last);
    else
        arr.extend();

        for i in reverse greatest(idx,2)..arr.last loop
            arr(i) := arr(i - 1);
        end loop;
    end if;

    arr(idx) := val;
    
end varchar2_tt_append;
/

测试:

declare
    ar  varchar2_tt := varchar2_tt('First', 'Second', 'Third', 'Fourth');
begin
    varchar2_tt_append
    ( arr => ar
    , pos => 1
    , val => 'New value' );

    for i in ar.first..ar.last loop
        dbms_output.put_line(i||' '||ar(i));
    end loop;
end;
1 New value
2 First
3 Second
4 Third
5 Fourth

推荐阅读