Oracle 程序太大(codegen 操作数)错误
Oracle program too large (codegen operands) error
我想从几千个点在 Oracle 中构建形状,但是在 运行 创建的代码中,我收到错误:
ORA-06550: program too large (codegen operands)
我达到了什么限制?我该如何克服它?
重现错误的类似代码(运行或在一分钟内失败):
declare
s clob;
begin
s := '
declare
type t_x is table of number index by pls_integer;
x t_x;
varr sdo_ordinate_array;
begin
';
for i in 1..23000 loop --21825: ok, 21850: error
s := s || 'x('||to_char(i)||') := 46.709864 + '||to_char(i)||'/23000;';
end loop;
s := s || '
varr := sdo_ordinate_array();
varr.extend(x.count);
for i in 1 .. x.count loop
varr(i) := x(i);
end loop;
end;';
execute immediate s;
end;
看来,批量收集可以解决这个问题。以下代码运行时间延长了 10 倍,但没有报错:
declare
s clob;
begin
s := '
declare
type t_x is table of number index by pls_integer;
x t_x;
varr sdo_ordinate_array;
begin
select coord
bulk collect into x
from (';
for i in 1..23000 loop --21825: ok, 21850: error
s := s || 'select '||to_char(i)||' rn, 46.709864 + '||to_char(i)||'/23000 coord from dual union all'||chr(10);
end loop;
s := s || '
select null,null from dual
)
where rn is not null
order by rn;
varr := sdo_ordinate_array();
varr.extend(x.count);
for i in 1 .. x.count loop
varr(i) := x(i);
end loop;
end;';
execute immediate s;
end;
为什么要将所有内容都放在一个动态语句中?看起来真的很奇怪。
像这样尝试:
declare
varr sdo_ordinate_array;
begin
varr := sdo_ordinate_array();
for i in 1..23000 loop
varr.extend;
varr(i) := 46.709864 + i/23000;
end loop;
end;
我不知道您的真实代码,但您也可以 return 来自立即执行的值,如本例所示。也许它可以简化您的问题。
DECLARE
type t_x is table of number index by pls_integer;
x t_x;
str varchar2(100);
BEGIN
FOR i in 10..20 LOOP
str := i|| ' * 2';
EXECUTE IMMEDIATE 'BEGIN :ret := '||str||'; END;' USING OUT x(i);
dbms_output.put_line(x(i));
END LOOP;
END;
我想从几千个点在 Oracle 中构建形状,但是在 运行 创建的代码中,我收到错误:
ORA-06550: program too large (codegen operands)
我达到了什么限制?我该如何克服它?
重现错误的类似代码(运行或在一分钟内失败):
declare
s clob;
begin
s := '
declare
type t_x is table of number index by pls_integer;
x t_x;
varr sdo_ordinate_array;
begin
';
for i in 1..23000 loop --21825: ok, 21850: error
s := s || 'x('||to_char(i)||') := 46.709864 + '||to_char(i)||'/23000;';
end loop;
s := s || '
varr := sdo_ordinate_array();
varr.extend(x.count);
for i in 1 .. x.count loop
varr(i) := x(i);
end loop;
end;';
execute immediate s;
end;
看来,批量收集可以解决这个问题。以下代码运行时间延长了 10 倍,但没有报错:
declare
s clob;
begin
s := '
declare
type t_x is table of number index by pls_integer;
x t_x;
varr sdo_ordinate_array;
begin
select coord
bulk collect into x
from (';
for i in 1..23000 loop --21825: ok, 21850: error
s := s || 'select '||to_char(i)||' rn, 46.709864 + '||to_char(i)||'/23000 coord from dual union all'||chr(10);
end loop;
s := s || '
select null,null from dual
)
where rn is not null
order by rn;
varr := sdo_ordinate_array();
varr.extend(x.count);
for i in 1 .. x.count loop
varr(i) := x(i);
end loop;
end;';
execute immediate s;
end;
为什么要将所有内容都放在一个动态语句中?看起来真的很奇怪。
像这样尝试:
declare
varr sdo_ordinate_array;
begin
varr := sdo_ordinate_array();
for i in 1..23000 loop
varr.extend;
varr(i) := 46.709864 + i/23000;
end loop;
end;
我不知道您的真实代码,但您也可以 return 来自立即执行的值,如本例所示。也许它可以简化您的问题。
DECLARE
type t_x is table of number index by pls_integer;
x t_x;
str varchar2(100);
BEGIN
FOR i in 10..20 LOOP
str := i|| ' * 2';
EXECUTE IMMEDIATE 'BEGIN :ret := '||str||'; END;' USING OUT x(i);
dbms_output.put_line(x(i));
END LOOP;
END;