drs*_*der 9 sql postgresql plpgsql
我在PostgreSQL 8.4中有一个存储过程,它根据作为参数传入的整数值调用另一个存储过程.调用那些存储过程,使它们返回一个整数列的关系.我遇到的问题是外部存储过程总是返回具有正确行数但具有所有id的NULL的关系.
这是存储过程简化为最简单的形式:
CREATE OR REPLACE FUNCTION spa(count integer)
RETURNS TABLE (id integer) AS $$
BEGIN
RETURN QUERY SELECT generate_series(1, count);
END;
$$ LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION spb(count integer)
RETURNS TABLE (id integer) AS $$
BEGIN
RETURN QUERY SELECT generate_series(1, count);
END;
$$ LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION conditional_relation_return(objectType integer, count integer)
RETURNS TABLE (id integer) AS $$
BEGIN
IF objectType = 1 THEN
RETURN QUERY SELECT id FROM spa(count);
ELSIF objectType = 2 OR objectType = 3 THEN
RETURN QUERY SELECT id FROM spb(count);
END IF;
END;
$$ LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)
如果你打电话:
# select * from conditional_relation_return(1, 2);
id
----
(2 rows)
Run Code Online (Sandbox Code Playgroud)
或者更具体地说:
# select count(*) from conditional_relation_return(1, 2) where id is null;
count
-------
2
(1 row)
Run Code Online (Sandbox Code Playgroud)
但是,如果您调用其中一个引用的存储过程,则会得到正确的结果:
# select * from spa(2);
id
----
1
2
(2 rows)
Run Code Online (Sandbox Code Playgroud)
那么为什么conditional_relation_return会返回所有NULL?
Mic*_*uen 13
在id与输出参数ID温泉冲突的(RETURNS TABLE (id integer)).Postgresql 8.4没有抱怨,它从out参数id而不是saner(spa的id)中选择id.
Postgresql 9.1抱怨您的原始代码:
ERROR: column reference "id" is ambiguous
LINE 1: SELECT id FROM spa(count)
^
DETAIL: It could refer to either a PL/pgSQL variable or a table column.
QUERY: SELECT id FROM spa(count)
CONTEXT: PL/pgSQL function "conditional_relation_return" line 4 at RETURN QUERY
Run Code Online (Sandbox Code Playgroud)
要解决此问题,请完全限定查询中的ID:
CREATE OR REPLACE FUNCTION conditional_relation_return(
objectType integer, count integer)
RETURNS TABLE (id integer) AS $$
BEGIN
IF objectType = 1 THEN
RETURN QUERY SELECT x.id FROM spa(count) as x;
ELSIF objectType = 2 OR objectType = 3 THEN
RETURN QUERY SELECT x.id FROM spb(count) as x;
END IF;
END;
$$ LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)
输出:
test=# select * from conditional_relation_return(1, 2);
id
----
1
2
(2 rows)
Run Code Online (Sandbox Code Playgroud)
Postgresql尊重您从中选择的列名称RETURNS TABLE.它仍然插槽x.id给id你的RETURNS TABLE.因此,即使您决定重命名RETURNS TABLE返回列的名称,它仍将插入x.id该名称,例如
CREATE OR REPLACE FUNCTION conditional_relation_return(
objectType integer, count integer)
RETURNS TABLE (hahah integer) AS $$
BEGIN
IF objectType = 1 THEN
RETURN QUERY SELECT x.id FROM spa(count) as x;
ELSIF objectType = 2 OR objectType = 3 THEN
RETURN QUERY SELECT x.id FROM spb(count) as x;
END IF;
END;
$$ LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)
输出:
test=# select * from conditional_relation_return(1, 2);
hahah
-------
1
2
(2 rows)
Run Code Online (Sandbox Code Playgroud)
请注意该hahah列