我正在开发一个使用模板生成针对Postgres数据库的数据访问层的实用程序。作为其中的一部分,我试图动态发现存储过程的返回类型。在返回单个标准类型的简单情况下,这很容易,但是当它返回用户定义的类型时,我很挣扎。
如果有人能提供必要的SQL来返回这些数据,我将不胜感激。
由于 标记
我很欣赏我到目前为止的答案,这些答案实际上归结为以下SQL
SELECT p.proname, t.typname, p,proretset
FROM pg_catalog.pg_proc p
LEFT JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace
INNER JOIN pg_type t ON p.prorettype = t.oid
WHERE n.nspname = 'public'
--and proname = 'foo'
ORDER BY proname;
这将返回返回类型的名称。但是,当它返回用户定义的类型时,我仍然需要将类型分解为构成它的属性。
在函数返回记录的情况下,除了调用函数并检查其返回值之外,我认为没有任何方法可以发现它的返回结构。
答案 0 :(得分:3)
psql
元命令是查找信息模式内容的简便快捷方式。
尝试test=# \d?
查找内省信息。
然后psql -E -c '\df'
将显示show function命令后面的sql:
d$ psql -E -c '\df+'
********* QUERY **********
SELECT n.nspname as "Schema",
p.proname as "Name",
pg_catalog.pg_get_function_result(p.oid) as "Result data type",
pg_catalog.pg_get_function_arguments(p.oid) as "Argument data types",
CASE
WHEN p.proisagg THEN 'agg'
WHEN p.proiswindow THEN 'window'
WHEN p.prorettype = 'pg_catalog.trigger'::pg_catalog.regtype THEN 'trigger'
ELSE 'normal'
END as "Type",
CASE
WHEN p.provolatile = 'i' THEN 'immutable'
WHEN p.provolatile = 's' THEN 'stable'
WHEN p.provolatile = 'v' THEN 'volatile'
END as "Volatility",
pg_catalog.pg_get_userbyid(p.proowner) as "Owner",
l.lanname as "Language",
p.prosrc as "Source code",
pg_catalog.obj_description(p.oid, 'pg_proc') as "Description"
FROM pg_catalog.pg_proc p
LEFT JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace
LEFT JOIN pg_catalog.pg_language l ON l.oid = p.prolang
WHERE pg_catalog.pg_function_is_visible(p.oid)
AND n.nspname <> 'pg_catalog'
AND n.nspname <> 'information_schema'
ORDER BY 1, 2, 4;
**************************
在你的情况下,这将是你想要的:
pg_catalog.pg_get_function_result(p.oid) as "Result data type",
答案 1 :(得分:2)
此查询将列出包含类型的存储过程。
SELECT proname, proargnames as arguments,
oidvectortypes(proargtypes) as arguments_type,
t.typname as return_type,prosrc as source
FROM pg_catalog.pg_namespace n
JOIN pg_catalog.pg_proc p ON pronamespace = n.oid
JOIN pg_type t ON p.prorettype = t.oid
WHERE nspname = 'public'
您始终可以按名称进行过滤。
答案 2 :(得分:1)
刚开始:
SELECT
*
FROM
pg_proc
JOIN pg_type ON pg_type.oid = ANY(proallargtypes)
WHERE
proname = 'foo';
答案 3 :(得分:1)
你在找这个吗?
SELECT proname, pg_get_function_result(oid) FROM pg_proc WHERE proname = 'foo';
答案 4 :(得分:1)
如果函数返回record
,那么直到运行时才知道该类型,用:
create or replace function func() returns record language plpgsql immutable as $$
declare
r record;
q record;
begin
select 10, 'hello' into r;
select 11, 'hello', 'helloagain' into q;
if random()>0.5 then
return r;
else
return q;
end if;
end;$$;
换句话说,在调用函数之后 之前,您无法知道类型。调用该函数后,您可以通过将record
传递给C语言函数来动态确定有关{{1}}的信息{/ 3}}
答案 5 :(得分:1)
感谢帮助人员,我认为JackPDouglas是正确的,因为返回记录集的函数可能是多态的,因此无法找到返回类型定义。
然而,这是我正在寻找的SQL,以获取返回复合类型的函数的定义:
SELECT t.typname, attname, a.typname
from pg_type t
JOIN pg_class on (reltype = t.oid)
JOIN pg_attribute on (attrelid = pg_class.oid)
JOIN pg_type a on (atttypid = a.oid)
WHERE t.typname = (
SELECT t.typname
FROM pg_catalog.pg_proc p
LEFT JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace
INNER JOIN pg_type t ON p.prorettype = t.oid
WHERE n.nspname = 'public'
and proname = 'foo'
ORDER BY proname
);