我猜这是包的一部分,否则你需要create or replace 语法。出于演示目的,我把它放在一个匿名块中只是为了测试编译。
两个问题:
-
integer 不需要精确,它只是 integer。
-
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/SQL if 条件由 then 关键字终止,因此它们不像其他语言那样需要括号,所以我删除了它们。
此外,您在顶部声明了变量idx、tmp 和val,它们在任何地方都没有使用,并且它们也与过程中的局部变量具有相同的名称,这可能会造成混淆。如果没有更多您未展示的代码使用它们,也许您可以摆脱它们。
编辑:根据要求,这是一个独立程序的样子:
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 插入到数组arr 的元素idx 中,将现有值上移一位。但是,它并不完全有效:
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