art*_*hur 8 postgresql type-conversion plpgsql functions composite-types
专有代码(我们无法更改)有一堆用户定义的函数类型:
create or replace function f() returns record as $$ ... $$
Run Code Online (Sandbox Code Playgroud)
我们通过以下方式调用它(例如):
SELECT status, log FROM f() as (status boolean, log text);
Run Code Online (Sandbox Code Playgroud)
(status boolean, log text)
是 table 的行类型T
。是否可以在不列出属性的情况下自动将record
(或setof record
返回类型)转换为T
行类型?我正在寻找的是那种:
SELECT * FROM f() as T%rowtype
Run Code Online (Sandbox Code Playgroud)
有一种方法。
给定一个表t
和一个f()
返回与该表类型匹配的匿名记录的函数:
CREATE TABLE t (id int, d date);
Run Code Online (Sandbox Code Playgroud)
你不能只是投匿名记录,因为是一个字段定义列表所需的
SELECT * FROM f()
Run Code Online (Sandbox Code Playgroud)
引用SELECT 命令的手册:
如果函数已定义为返回记录数据类型,则
AS
必须存在别名或关键字,后跟表单中的列定义列表...
大胆强调我的。
因此,虽然所有这些查询都有效:
SELECT '(1,2013-11-11)'::t;
SELECT ('(1,2013-11-11)'::t).*;
SELECT f(); -- returning anonymous record
SELECT * FROM f() AS f(id int, d date);
Run Code Online (Sandbox Code Playgroud)
这些都没有:
SELECT * FROM f();
SELECT * FROM f()::t;
Run Code Online (Sandbox Code Playgroud)
后者引发异常:
错误:无法将类型记录转换为 t
您可以将SELECT
with 列定义列表包装到@a_horse和@deszo建议的VIEW
or 函数中。那会工作得很好:
CREATE OR REPLACE VIEW v1 AS
SELECT * FROM f() AS f(id int, d date);
Run Code Online (Sandbox Code Playgroud)
但这不会回答你的问题:
将记录(或 setof 记录返回类型)转换为
T
rowtype 而不列出属性?
当强制转换失败时,plpgsql 中的赋值有效。
CREATE OR REPLACE function f1(OUT rec t) AS
$func$
BEGIN
rec := f(); -- assignment succeeds where cast failed (!)
END
$func$ LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)
称呼:
SELECT * FROM f1();
Run Code Online (Sandbox Code Playgroud)
虽然你也可以用这种模式编写一个集合返回函数,但我没有找到一种方法来SELECT
从集合返回函数而不提供列定义列表......
归档时间: |
|
查看次数: |
8791 次 |
最近记录: |