是否可以从 Postgres 函数中发现列类型?

发布于 2024-10-06 18:35:55 字数 589 浏览 3 评论 0原文

我正在开发一个实用程序,该实用程序使用模板针对 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;

这将返回返回类型的名称。然而,我仍然需要将类型分解为当它返回用户定义类型时组成它的属性。

在函数返回记录的情况下,我认为除了调用函数并检查其返回值之外,没有任何方法可以发现其返回结构。

I'm working on a utility that is using templates to generate a data access layer against a Postgres database. As part of this I'm trying to dynamically discover the return types of the stored procedures. This is easy enough in simple cases where a single standard type is returned, but I'm struggling when it comes to it returning a user defined type.

I'd appreciate if someone could provide the necessary SQL to return this data.

Thanks
Mark

I appreciate the answers that I have so far, which effectively boil to to the following 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;

This will return the name of the return types. However I still need to decompose the type into the properties that make it up when it returns a user defined type.

In the case that a function returns a record I don't think there is any way to discover its return structure other than calling the function and examining its return values.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

删除→记忆 2024-10-13 18:35:55

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",

psql meta commands are an easy shortcut to finding information schema stuff.

try test=# \d? to find introspection info.

then psql -E -c '\df' will show the sql behind the show function command:

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;
**************************

In your case the would be what you want:

 pg_catalog.pg_get_function_result(p.oid) as "Result data type",
稚气少女 2024-10-13 18:35:55

此查询将列出带有类型的存储过程。

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'  

您始终可以按昵称进行过滤。

This query will list the stored procedures with the types.

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'  

You can always filter by proname.

泪眸﹌ 2024-10-13 18:35:55

刚开始:

SELECT 
  * 
FROM 
  pg_proc 
    JOIN pg_type ON pg_type.oid = ANY(proallargtypes) 
WHERE 
  proname = 'foo';

Just to get started:

SELECT 
  * 
FROM 
  pg_proc 
    JOIN pg_type ON pg_type.oid = ANY(proallargtypes) 
WHERE 
  proname = 'foo';
浅唱ヾ落雨殇 2024-10-13 18:35:55

您在找这个吗?

SELECT proname, 
       pg_get_function_result(oid)
FROM pg_proc
WHERE proname = 'foo';

Are you looking for this?

SELECT proname, 
       pg_get_function_result(oid)
FROM pg_proc
WHERE proname = 'foo';

够运 2024-10-13 18:35:55

如果函数返回记录,则直到运行时才知道类型,如下所示:

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;$;

换句话说,在调用之后之前,您无法知道类型函数。调用该函数后,您可以将有关记录的信息传递到参考此处

if the function returns a record then the type is not known until runtime, demonstrated with:

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;$;

in other words, you can't know the type until after you call the function. Once you have called the function, you could dynamically determine information about the record by passing it into a C-language function as referenced here

新雨望断虹 2024-10-13 18:35:55

感谢大家的帮助,我认为 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
);

Thanks for the help guys, I'm think JackPDouglas is correct and that since functions that return record sets can be polymorphic that there's no way to find out the return type definition.

However here's the SQL I was looking for to get the definition of a function that returns a composite type:

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
);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文