标签: plpgsql

pg_restore 错误:扩展安装顺序不正确

我有一个安装了 pg_cron 扩展的 PostgreSQL 9.5 服务器。testdb我正在使用以下命令创建名为的数据库的备份:

$ pg_dump -c -U postgres -Fc -f test.dump testdb
Run Code Online (Sandbox Code Playgroud)

当我尝试在已通过 yum 安装的干净 PostgreSQL 9.5 上恢复数据库时pg_cron,我看到错误消息,指出pg_cron无法安装扩展,因为plpgsql扩展不存在:

$ pg_restore -Fc -d testdb -c -U postgres test.dump
pg_restore: [archiver (db)] Error while PROCESSING TOC:
pg_restore: [archiver (db)] Error from TOC entry 4; 3079 18235 EXTENSION pg_cron
pg_restore: [archiver (db)] could not execute query: ERROR:  extension "pg_cron" does not exist
    Command was: DROP EXTENSION pg_cron;

pg_restore: [archiver (db)] could not …
Run Code Online (Sandbox Code Playgroud)

plpgsql pg-dump postgresql-9.5 pg-restore

5
推荐指数
0
解决办法
1085
查看次数

如何使用 format() 函数引用限定表名?

format我在使用下面示例中的函数正确引用表名时遇到一些问题。

CREATE OR REPLACE FUNCTION copy_table(_source_tbl regclass, _target_tbl text)
 RETURNS bool AS $func$
DECLARE query_str text; 
BEGIN
  query_str = format($fmt$ DROP TABLE IF EXISTS %1$I; CREATE TABLE %1$I AS (TABLE %s); $fmt$, _target_tbl, _source_tbl);
  EXECUTE query_str;
  RAISE NOTICE '%', query_str;
 RETURN True;
END $func$ LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)

我的困境是我想引用输入表名称_target_tbl作为标识符(以避免 SQL 注入)。但是,给定完整的表名称ex.test1,这会导致架构部分ex.被视为表名称的一部分,并public."ex.test1"在默认public.架构中创建表,如下所示。

我应该如何在此处正确引用/格式化标识符?

=> SELECT copy_table('ex.test', 'ex.test1');
NOTICE:  table "ex.test1" does not exist, skipping
NOTICE:   DROP TABLE IF EXISTS "ex.test1"; CREATE TABLE …
Run Code Online (Sandbox Code Playgroud)

postgresql dynamic-sql plpgsql postgresql-10

5
推荐指数
1
解决办法
3448
查看次数

动态定义一个RETURN表(列类型,名称)用于后续循环

我想对ST_Intersection(clipper_geom, clipped_geom)来自表的行数执行。

https://postgis.net/docs/ST_Intersection.html

https://postgis.net/docs/ST_Intersects.html

POSTGIS 交集本身不支持处理多个几何图形,这与ST_Intersects()我必须设计一个函数(返回一个表)来选择与我的clipper_geomusing相交的行ST_Intersects()、循环遍历结果集并计算与 的每个交集有关ST_Intersection()。字段geomclipped_geom_wkt是记录剪裁几何体的字段。

该功能有效,但我需要为每个要生成剪辑的表使用不同的功能。我想动态读取输入表(列名称和类型)并在RETURN语句中定义两者。

所有字段名称和类型都相同,只是geom更新和clipped_geom_wkt添加。

我尝试搜索 Stack Overflow,找到了有关如何创建动态表结构的示例,但没有一个LOOP对第一个结果执行后续操作,其中列名必须匹配才能插入/更新新数据。

这是我到目前为止所提出的,但我不确定如何执行该LOOP部分、添加clipped_geom_wkt字段和更新geom字段。一些回复建议RETURNS TABLE (...)如果添加更多字段SETOF...

/sf/ask/1247503771/

但似乎动态生成的列仅支持RETURNS SETOF ...

/sf/ask/821817951/#11751557

/sf/ask/602362211/#8611675

CREATE OR REPLACE FUNCTION clip_palin_polygon_complete(clipped_table text,clipper_geom text, age_sequence VARCHAR)
RETURNS TABLE (rec clipped_table, clipped_geom_wkt text)) AS $$ --not sure if this is the right way to …
Run Code Online (Sandbox Code Playgroud)

postgresql dynamic-sql plpgsql postgis

5
推荐指数
1
解决办法
1万
查看次数

“不要使用错误进行流量控制”公理适用于 postgres 吗?

在传统编程中,有一条公理:“不要使用错误进行流程控制”。一个常见的示例是抛出错误然后捕获错误,而不是使用普通的条件语句或break语句。这是有害的,因为应用程序必须展开调用堆栈并调用一些相对昂贵的异常处理逻辑,而不是简单地处理条件语句。

我正在使用 Postgres 系统,其中用户在 Postgres 中调用一个函数,该函数在不满足条件时抛出错误而不是不返回任何行。该条件大致是“此输入值不存在,无事可做”,而不是真正的例外情况。

当以与传统编程类似的方式抛出错误时,Postgres 是否会产生运行时成本?换句话说,在 Postgres 中使用异常作为流量控制对性能有害还是只是草率?

postgresql condition error-handling plpgsql

5
推荐指数
1
解决办法
407
查看次数

何时(或为何)使用 PLPython(3)u

随着我获得更多 PostgreSQL 经验,我开始质疑 PLPython 的存在。它被认为是一种“不受信任”的语言https://www.postgresql.org/docs/10/plpython.html

我想知道的是,何时或为什么有人需要使用它?PLPGSQL 已经是一种非常强大的语言,可以让您做很多事情。这里有人需要使用它吗?如果需要,用途是什么?

postgresql plpgsql plpython

5
推荐指数
1
解决办法
3399
查看次数

在存储过程中返回记录集

我想从 pl/pgsql 返回一组记录。有没有办法在不使用“for”构造和游标的情况下做到这一点?例如,当我比较这两个存储过程时:

create or replace function sqlProc () returns setof integer as $$                                                                                                                                              
  select * from foo;
$$ language sql;


create or replace function plpgSqlProc () returns setof integer as $$
declare
  c integer;
begin
  for c in select * from foo loop
    return next c;
end loop;

end;
$$ language plpgsql;
Run Code Online (Sandbox Code Playgroud)

纯 SQL 版本的时间性能是 pl/pgsql 版本的 2 倍!不幸的是,我还有其他无法用纯 SQL 表达的逻辑,所以我想知道应该如何编写存储过程?

postgresql stored-procedures plpgsql set-returning-functions

4
推荐指数
1
解决办法
3589
查看次数

返回表的无类型函数

我想编写一个 PostgreSQL 存储函数,它的行为本质上类似于我从 MSSQL 和 MySQL 中了解和喜爱的存储过程,我可以在其中包装一个不带参数的查询并让它返回该结果集,而无需指定输出的格式并在每次更新查询时更改该定义。这在 PostgreSQL 中甚至可能吗?

我使用 PostgreSQL 9.2 尝试了以下操作:

CREATE OR REPLACE FUNCTION test()
RETURNS SETOF record
Run Code Online (Sandbox Code Playgroud)

这给了我以下错误:

错误:返回“记录”的函数需要列定义列表

我也试过:

CREATE OR REPLACE FUNCTION test()
RETURNS table ()
Run Code Online (Sandbox Code Playgroud)

但显然这是无效的语法。

postgresql datatypes plpgsql functions

4
推荐指数
1
解决办法
5621
查看次数

使用 := 运算符赋值

当我分配一个变量时

result := title || '', by '' || author;
Run Code Online (Sandbox Code Playgroud)

运行该函数需要更多时间(大约 15 秒)。
但是,当我分配变量时

result = title || '', by '' || author;
Run Code Online (Sandbox Code Playgroud)

只需要133ms。

为什么第一个场景需要更多时间?这背后的原因是什么?

下面给出了完整的功能。

CREATE OR REPLACE FUNCTION myschema.fn_get_res_no(reservation_no character varying)
  RETURNS character varying AS
$BODY$  

DECLARE  
    emd_status_firstcall varchar(2);  
    emd_status_secondcall varchar(2);
    emd_status      varchar(6);  
BEGIN  
    SELECT firstwscomplete, secondwscomplete
    INTO emd_status_firstcall, emd_status_secondcall
    FROM myschema.mytable
    WHERE respkgconfirmid = reservation_no;

    emd_status = emd_status_firstcall || ', ' || emd_status_secondcall;
    RETURN emd_status ;  

END;  
$BODY$
  LANGUAGE plpgsql VOLATILE;
Run Code Online (Sandbox Code Playgroud)

postgresql performance plpgsql postgresql-performance

4
推荐指数
1
解决办法
8152
查看次数

仅当查询结果不为 NULL 时如何正确返回查询结果?

我正在编写一个 PL/pgSQL 函数,它为我需要检查它是否返回某些内容的查询创建一个游标。

我正在做的是这样的:

  1. 运行查询
  2. 检查它是否返回一些东西。
  3. 如果没有,请将参数加倍并再次运行查询。
  4. 否则,返回查询中的所有行。

我发现,检查,如果该查询返回的东西用光标是最好的选择,因为它(加入5个表和大量列)一个很长的查询和SELECT ... INTO不正确的顺心,因为我必须创建一个TYPE自查询具有来自一个表的列和用于距离计算的列。

问题是我目前仅使用游标来检查查询是否在我打开和关闭它的循环中返回了某些内容。一旦查询返回某些内容,我就退出循环并返回查询。我可以马上说,这是我需要的丑陋的解决方法。也许有人可以帮助我解决这个问题。

这是一些显示我目前正在做的事情的代码。

CREATE FUNCTION store_distance(
    latitude double precision,
    longitude double precision,
    radius double precision,
    tries integer
)
RETURNS TABLE(
    store_id store.id%type,
    store_name store.name%type,
    distance double precision
)
AS
$$
DECLARE
    cur_stores CURSOR FOR
        SELECT
            store.id,
            store.name,
            get_distance(latitude, longitude, store.latitude, store.longitude) distance
        FROM
            store
        WHERE
            store.latitude BETWEEN (latitude - radius) AND (latitude + radius)
            AND store.longitude BETWEEN (longitude - radius) AND (longitude + radius)
        ORDER BY …
Run Code Online (Sandbox Code Playgroud)

postgresql performance spatial plpgsql query-performance

4
推荐指数
1
解决办法
2998
查看次数

如何触发日志消息中的换行符?

日志消息是否可以跨越多行?我期待:

RAISE WARNING 'Line 1\nLine 2';

导致以下日志:

Line 1
Line 2
Run Code Online (Sandbox Code Playgroud)

但相反,我得到:

Line 1\nLine 2

有任何想法吗?

postgresql plpgsql

4
推荐指数
1
解决办法
3786
查看次数