在函数(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您甚至可以访问引发的超出范围的元素wihtout异常:
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表达式不能为null
因此,在某些情况下,必须初始化数组。让我们检查一下,然后我们来看看初始化和非初始化之间的区别:
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)
发布于 2016-08-25 21:59:04
在plpgsql函数中,我通常在declare中初始化数组。
declare
arr int[] = '{}';当然,非初始化数组是空的。
要区分空数组和空数组,可以使用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)https://stackoverflow.com/questions/39154944
复制相似问题