首页 > 解决方案 > 如何执行数组初始化

问题描述

我正在尝试检查数组索引元素是否存在。它没有按预期工作。我将代码连同预期的输出和所有细节一起发布。

PostgreSQL 代码:

do $$
begin 
   CREATE DOMAIN vararraytype AS numeric(9)[];
END$$;

do $$
begin
create type custschema.coldata_r as (sno numeric, cname varchar, dids integer, dloc varchar2);
END $$;

do $$
begin
create domain custschema.coldata as coldata_r[];
END $$;

CREATE OR REPLACE FUNCTION custschema.upds_func(
p_indarray vararraytype)
RETURNS void AS
$body$
    declare
        v_col_array      custschema.colrectab;
        v_columnRec        custschema.colrec;
        rec record;
        clmdata custschema.coldata; 
begin
for rec in (select sno,cname,dids,dloc from customer where custid='CUST12')
                  loop
                    clmdata[rec.sno]:=rec;
                    raise info ' clmdata[rec.sno] %',clmdata[rec.sno];
                  end loop;
raise info 'p_indarray %',array_length(p_indarray,1);
for x IN 1 .. coalesce(array_length(p_indarray,1),0) 
loop
v_columnRec.colIndex := p_indarray[x] + 2;
raise info 'v_columnRec.colIndex %',v_columnRec.colIndex;

perform custschema.arrayindex(v_columnRec.colIndex)

v_col_array[x] := v_columnRec;
end loop;
end $body$ language plpgsql;

**Output of raise info  from "custschema.upds_func" function.**
raise info ' clmdata[rec.sno] %',clmdata[rec.sno];

clmdata[rec.sno] (1,Abi,15,Hyd)
clmdata[rec.sno] (2,Jhon,15,Mum)
clmdata[rec.sno] (3,Thomas,20,Bang)
clmdata[rec.sno] (4,Marry,25,SYD)
clmdata[rec.sno] (5,Tina,7,KCP)
clmdata[rec.sno] (6,Jorge,10,LOL)
clmdata[rec.sno] (7,Michal,15,CHE)
clmdata[rec.sno] (8,Chanu,9,USA)

raise info 'p_indarray %',array_length(p_indarray,1); -- O/P 3
raise info 'v_columnRec.colIndex %',v_columnRec.colIndex; -- O/P 3


create or replace  function custschema.arrayindex(atrindx  IN NUMERIC,cname   out VARCHAR) AS
$body$
declare 
clmdata custschema.coldata;
begin
raise info 'atrindx %',atrindx;
raise info 'sno %',clmdata[attrIndex].sno;
if clmdata[atrindx].sno IS NULL then
raise exception e'%',  'invalid index';
end if;
cname := clmdata[atrindx].col_nme;
end $body$ language plpgsql;

**Output of raise info  from "custschema.arrayindex" function.**
raise info 'atrindx %',atrindx;  --O/P 3
raise info 'sno %',clmdata[attrIndex].sno; -- O/P NULL

Then raising the exception "invalid index".

甲骨文代码。

procedure arrayindex(atrindx  IN integer,cname   OUT varchar2) 
is
v_sno integer;
begin
dbms_output.put_line('atrindx' ||atrindx);
v_sno:=clmdata(attrIndex).sno;
dbms_output.put_line('v_sno'||v_sno );
if (not clmdata.exists(atrindx)) then  
gnvGen.toStr(attrIndex-2));
raise ind_excetion;
end if;
cname := clmdata(atrindx).col_nme;
end;

dbms_output.put_line('atrindx' ||atrindx); -- O/P 3
dbms_output.put_line('v_sno'||v_sno );
v_sno 3
v_sno 4
v_sno 5

在 Oracle v_sno:=clmdata(attrIndex).sno; 给出数据为 3,4,5。而在 PostgreSQL v_sno:=clmdata(attrIndex).sno; 给NULL。

标签: arrayspostgresql

解决方案


问题很可能是IF条件。

这个表达式:

if (not (coalesce(clmdata[atrindx]::text,'') <> '' and coalesce(array_length(clmdata,1),0) < 1)

这个表达式在语法上是错误的,所以CREATE FUNCTION语句会失败。

所以你的实际功能一定是不同的。

您应该将检查简化为

IF clmdata[atrindx] IS NULL THEN
   RAISE EXCEPTION 'invalid index';
END IF;

此外,很可能是

clmdata[atrindx] IS NOT NULL

(clmdata[atrindx]).col_nme IS NULL

IS NULL仅当其所有组件均为 NULL 时才为复合类型。

一般建议:编写更清晰、缩进良好的代码,这样您将有更好的时间调试它。


推荐阅读