我有一个安装了 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) 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) 我想对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()。字段geom和clipped_geom_wkt是记录剪裁几何体的字段。
该功能有效,但我需要为每个要生成剪辑的表使用不同的功能。我想动态读取输入表(列名称和类型)并在RETURN语句中定义两者。
所有字段名称和类型都相同,只是geom更新和clipped_geom_wkt添加。
我尝试搜索 Stack Overflow,找到了有关如何创建动态表结构的示例,但没有一个LOOP对第一个结果执行后续操作,其中列名必须匹配才能插入/更新新数据。
这是我到目前为止所提出的,但我不确定如何执行该LOOP部分、添加clipped_geom_wkt字段和更新geom字段。一些回复建议RETURNS TABLE (...)如果添加更多字段SETOF...
但似乎动态生成的列仅支持RETURNS SETOF ...
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) 在传统编程中,有一条公理:“不要使用错误进行流程控制”。一个常见的示例是抛出错误然后捕获错误,而不是使用普通的条件语句或break语句。这是有害的,因为应用程序必须展开调用堆栈并调用一些相对昂贵的异常处理逻辑,而不是简单地处理条件语句。
我正在使用 Postgres 系统,其中用户在 Postgres 中调用一个函数,该函数在不满足条件时抛出错误而不是不返回任何行。该条件大致是“此输入值不存在,无事可做”,而不是真正的例外情况。
当以与传统编程类似的方式抛出错误时,Postgres 是否会产生运行时成本?换句话说,在 Postgres 中使用异常作为流量控制对性能有害还是只是草率?
随着我获得更多 PostgreSQL 经验,我开始质疑 PLPython 的存在。它被认为是一种“不受信任”的语言https://www.postgresql.org/docs/10/plpython.html
我想知道的是,何时或为什么有人需要使用它?PLPGSQL 已经是一种非常强大的语言,可以让您做很多事情。这里有人需要使用它吗?如果需要,用途是什么?
我想从 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
我想编写一个 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)
但显然这是无效的语法。
当我分配一个变量时
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) 我正在编写一个 PL/pgSQL 函数,它为我需要检查它是否返回某些内容的查询创建一个游标。
我正在做的是这样的:
我发现,检查,如果该查询返回的东西用光标是最好的选择,因为它(加入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) 日志消息是否可以跨越多行?我期待:
RAISE WARNING 'Line 1\nLine 2';
导致以下日志:
Line 1
Line 2
Run Code Online (Sandbox Code Playgroud)
但相反,我得到:
Line 1\nLine 2
有任何想法吗?
plpgsql ×10
postgresql ×9
dynamic-sql ×2
performance ×2
condition ×1
datatypes ×1
functions ×1
pg-dump ×1
pg-restore ×1
plpython ×1
postgis ×1
spatial ×1