内部函数(plpgsql)和代码块我测试了pgsql真的不需要初始化数组。
试试这个:我只是在附加一个元素之前和之后测试数组长度。
do $$
declare ai int[];
begin
--BEFORE
raise notice 'ai length: %', array_length(ai,1);
--append the element (to the NON initialized array)
ai = array_append(ai,'2016');
--AFTER
raise notice 'ai length: %', array_length(ai,1);
end;
$$
没有错误,结果是:
NOTICE: ai length: <NULL>
NOTICE: ai length: 1
您甚至可以在抛出异常时访问越界元素:
begin
raise notice 'ai length: %', array_length(ai,1);
raise notice 'element 99: %', ai[99];
输出:
注意:ai长度:NULL
注意:元素99:NULL
所以你开始认为数组以某种方式进行了懒惰初始化,只需使用它们。 但情况并非总是如此,请考虑以下代码:
do $$
declare ai int[];
declare i int;
begin
foreach i in array ai loop
raise notice 'Element: %', i;
end loop;
end; $$
此 会抛出错误!以下内容:
错误:FOREACH表达式不能为空
因此,在某些情况下,数组已进行初始化。 让我们检查,让我们发现初始化与非初始化之间的区别:
do $$
declare ai int[];
declare x int;
declare i int;
begin
raise notice 'Array length: %', array_length(ai,1);
ai = array[] :: int[];
raise notice 'Array length: %', array_length(ai,1);
foreach i in array ai loop
raise notice 'Element: %', i;
end loop;
end;
$$
输出:
注意:数组长度:NULL
注意:数组长度:NULL
所以:行
ai = array[] :: int[];
工作,实际上for循环不再抛出异常。
但是,在初始化之后,
raise notice 'Array length: %', array_length(ai,1);
仍然给'null',这很奇怪。
问题是:我初始化阵列的方式是否正确?
对这种奇怪的行为有解释吗?
(Postgres版本:9.5)
答案 0 :(得分:2)
在plpgsql函数中,我通常在declare
中初始化数组:
declare
arr int[] = '{}';
非初始化数组当然是null。
要区分空数组和空数组,可以使用cardinality()
代替array_length()
:
with data(ar) as (
values (array[1]), (array[]::int[]), (null)
)
select ar "array", ar isnull "isnull?", array_length(ar, 1), cardinality(ar)
from data;
array | isnull? | array_length | cardinality
-------+---------+--------------+-------------
{1} | f | 1 | 1
{} | f | | 0
| t | |
(3 rows)