Lou*_*s93 3 postgresql casting plpgsql
我有一个像这样组织的功能:
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;
Run Code Online (Sandbox Code Playgroud)
我有一个表,其中包含组织waypoint数据类型结构的方式.此表未明确表示类型waypoint本身.
该函数按原样创建,但是,我无法通过传入我的表来调用它:
select everything(waypoints);
要么 select everything(select * from temp);
但它表示select前者和后面的语法错误或后者waypoints不存在语法错误.
我该怎么办?
在Postgres 9.4中测试的所有内容.
Postgres在处理ROW类型的语法中有一些弱点.你不能直接从表(别名)转换:
SELECT w::waypoint FROM waypoints w;Run Code Online (Sandbox Code Playgroud)
Run Code Online (Sandbox Code Playgroud)ERROR: cannot cast type waypoints to waypoint
解决方案只有一步之遥:分解子查询中的行,然后执行转换.这样,列值被分解并直接包装到新类型中,而不会转换为text后退.无需单独列出所有列,也无需创建自定义强制转换:
SELECT (w.*)::waypoint FROM (SELECT * FROM waypoints) w;
Run Code Online (Sandbox Code Playgroud)
或更短:
SELECT w.*::waypoint FROM (TABLE waypoints) w;
Run Code Online (Sandbox Code Playgroud)
或者更短,但是:
SELECT w::waypoint FROM (TABLE waypoints) w;
Run Code Online (Sandbox Code Playgroud)
这是更短更快,在快速测试中有30k行和简单类型,比铸造text和返回快10倍.如果您有(大)jsonb列或任何复杂类型(昂贵的转换/来自text),差异将会更大.
更重要的是,您不需要其他自定义复合(ROW)类型.每个表都已将其行自动定义为类型.只需使用现有的类型waypoints,而不是waypoint(如果可能的话).那你需要的只是:
SELECT w FROM waypoints w;
Run Code Online (Sandbox Code Playgroud)
或者,为您的例子:
SELECT everything(t) FROM temp t; -- using type waypoints
SELECT everything(t::waypoint) FROM (TABLE temp) t; -- using type waypoint
Run Code Online (Sandbox Code Playgroud)
旁白:
你没有传递一个table parameter to this function,而是一个行值.这就是你按名称传递一个表的方法:
你不能直接在Postgres中"传递整个表"作为参数,没有表变量.您可以使用游标或临时表.
您的函数具有无效的类型声明,并且不必要地复杂.我严重怀疑你想创建一个视图:
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;
Run Code Online (Sandbox Code Playgroud)
text array是无效的语法,text[]而是使用声明一个数组text.
而不是使用表/类型名称waypoints作为函数参数名称,这将使您容易混淆错误.
或者只是使用一个简单的SQL函数,如果您的案例如演示一样简单:
CREATE FUNCTION everything(_wp waypoint) -- or use type waypoints
RETURNS TABLE(node int, xy text[]) AS
$func$
SELECT ...
$func$ LANGUAGE sql;
Run Code Online (Sandbox Code Playgroud)
不要引用语言名称.这是一个标识符.
| 归档时间: |
|
| 查看次数: |
3016 次 |
| 最近记录: |