如何将 table 参数传递给此函数?
How do I pass in a table parameter to this function?
我有一个这样组织的函数:
create function everything(waypoints waypoint)
returns table(node int, xy text array) as $$
BEGIN
create view results as ...
return query (select * from results);
END;
$$ LANGUAGE plpgsql;
我有一个 table 参数以 waypoint
数据类型的结构方式组织。这个 table 本身并不是明确的 waypoint
类型。
该函数已按预期创建,但是,我无法通过传入我的 table 来调用它:
select everything(waypoints);
或select everything(select * from temp);
但它说后者在 select
处或附近存在语法错误,前者不存在 waypoints
列。
我该如何继续?
如果 waypoint
和 temp
中的所有类型都可以转换为 text
,您可以序列化和反序列化 text
:
SELECT everything(temp::text::waypoint)
FROM temp
但是,显式构造会更简洁:
SELECT everything((col1, col2, col3, ...)::waypoint)
FROM temp
或创建 CAST
:
CREATE FUNCTION temp_to_waypoint (temp)
RETURNS waypoint
AS
$$
SELECT (col1, col2, col3, ...)::waypoint
$$
LANGUAGE 'sql';
CREATE CAST (temp AS waypoint) WITH FUNCTION temp_to_waypoint (test) AS IMPLICIT;
SELECT everything(temp)
FROM temp;
一切都在 Postgres 中测试 9.4.
Postgres 在处理 ROW 类型的语法上有一些弱点。您不能直接从 table(别名)投射:
<strike>SELECT w::waypoint FROM waypoints w;</strike>
ERROR: cannot cast type waypoints to waypoint
解决方案仅一步之遥:分解子查询中的行,然后进行转换。这样,列值被分解并直接包装到新类型中,而无需强制转换为 text
并返回。无需单独列出所有列,也无需创建自定义转换:
SELECT (w.*)::waypoint FROM (SELECT * FROM waypoints) w;
或更短:
SELECT w.*::waypoint FROM (TABLE waypoints) w;
或更短,但:
SELECT w::waypoint FROM (TABLE waypoints) w;
在具有 30k 行和简单类型的快速测试中,这比转换到 text
和返回快 10 倍。如果您有(大)jsonb
列或任何复杂类型(昂贵的转换 to/from text
),差异会更大。
更重要的是,您不需要 另一种自定义复合 (ROW) 类型。每个 table 都已将其行自动定义为类型。只需使用现有类型 waypoints
而不是 waypoint
(如果可能的话)。那么你只需要:
SELECT w FROM waypoints w;
或者,对于您的示例:
SELECT everything(t) FROM temp t; -- using type waypoints
SELECT everything(t::waypoint) FROM (TABLE temp) t; -- using type waypoint
旁白:
- A table 没有 "arguments" 但列。
您不是传递table parameter to this function
,而是行值。这就是按名称传递 table 的方式:
- Table name as a PostgreSQL function parameter
您不能在 Postgres 中直接将 "pass a whole table" 作为参数,没有 table 变量。为此,您可以使用游标或临时 table。
函数
您的函数具有无效的类型声明并且不必要地复杂。我严重怀疑你想创建一个视图:
CREATE FUNCTION everything(_wp waypoint) -- or use type waypoints
RETURNS TABLE(node int, xy text[]) AS
$func$
BEGIN
RETURN QUERY
SELECT ...
END
$func$ LANGUAGE plpgsql;
text array
不是有效语法,使用 text[]
代替声明 text
.
的数组
最好不要使用 table / 类型名称 waypoints
作为函数参数名称,这会使您容易混淆错误。
或者,如果您的案例像演示的那样简单,则只需使用一个简单的 SQL 函数:
CREATE FUNCTION everything(_wp waypoint) -- or use type waypoints
RETURNS TABLE(node int, xy text[]) AS
$func$
SELECT ...
$func$ LANGUAGE sql;
不要引用语言名称。这是一个标识符。
我有一个这样组织的函数:
create function everything(waypoints waypoint)
returns table(node int, xy text array) as $$
BEGIN
create view results as ...
return query (select * from results);
END;
$$ LANGUAGE plpgsql;
我有一个 table 参数以 waypoint
数据类型的结构方式组织。这个 table 本身并不是明确的 waypoint
类型。
该函数已按预期创建,但是,我无法通过传入我的 table 来调用它:
select everything(waypoints);
或select everything(select * from temp);
但它说后者在 select
处或附近存在语法错误,前者不存在 waypoints
列。
我该如何继续?
如果 waypoint
和 temp
中的所有类型都可以转换为 text
,您可以序列化和反序列化 text
:
SELECT everything(temp::text::waypoint)
FROM temp
但是,显式构造会更简洁:
SELECT everything((col1, col2, col3, ...)::waypoint)
FROM temp
或创建 CAST
:
CREATE FUNCTION temp_to_waypoint (temp)
RETURNS waypoint
AS
$$
SELECT (col1, col2, col3, ...)::waypoint
$$
LANGUAGE 'sql';
CREATE CAST (temp AS waypoint) WITH FUNCTION temp_to_waypoint (test) AS IMPLICIT;
SELECT everything(temp)
FROM temp;
一切都在 Postgres 中测试 9.4.
Postgres 在处理 ROW 类型的语法上有一些弱点。您不能直接从 table(别名)投射:
<strike>SELECT w::waypoint FROM waypoints w;</strike>
ERROR: cannot cast type waypoints to waypoint
解决方案仅一步之遥:分解子查询中的行,然后进行转换。这样,列值被分解并直接包装到新类型中,而无需强制转换为 text
并返回。无需单独列出所有列,也无需创建自定义转换:
SELECT (w.*)::waypoint FROM (SELECT * FROM waypoints) w;
或更短:
SELECT w.*::waypoint FROM (TABLE waypoints) w;
或更短,但:
SELECT w::waypoint FROM (TABLE waypoints) w;
在具有 30k 行和简单类型的快速测试中,这比转换到 text
和返回快 10 倍。如果您有(大)jsonb
列或任何复杂类型(昂贵的转换 to/from text
),差异会更大。
更重要的是,您不需要 另一种自定义复合 (ROW) 类型。每个 table 都已将其行自动定义为类型。只需使用现有类型 waypoints
而不是 waypoint
(如果可能的话)。那么你只需要:
SELECT w FROM waypoints w;
或者,对于您的示例:
SELECT everything(t) FROM temp t; -- using type waypoints
SELECT everything(t::waypoint) FROM (TABLE temp) t; -- using type waypoint
旁白:
- A table 没有 "arguments" 但列。
您不是传递
table parameter to this function
,而是行值。这就是按名称传递 table 的方式:- Table name as a PostgreSQL function parameter
您不能在 Postgres 中直接将 "pass a whole table" 作为参数,没有 table 变量。为此,您可以使用游标或临时 table。
函数
您的函数具有无效的类型声明并且不必要地复杂。我严重怀疑你想创建一个视图:
CREATE FUNCTION everything(_wp waypoint) -- or use type waypoints
RETURNS TABLE(node int, xy text[]) AS
$func$
BEGIN
RETURN QUERY
SELECT ...
END
$func$ LANGUAGE plpgsql;
text array
不是有效语法,使用 text[]
代替声明 text
.
最好不要使用 table / 类型名称 waypoints
作为函数参数名称,这会使您容易混淆错误。
或者,如果您的案例像演示的那样简单,则只需使用一个简单的 SQL 函数:
CREATE FUNCTION everything(_wp waypoint) -- or use type waypoints
RETURNS TABLE(node int, xy text[]) AS
$func$
SELECT ...
$func$ LANGUAGE sql;
不要引用语言名称。这是一个标识符。