在postgresql plpgsql中,
create function f1( p_i int ) returns table( c1 int ) as $$
begin
-- wish to exit, do not wish to return anything
if p_i < 0 then
-- cannot RETURN - since can only return record!
end if;
-- continue processing
return query select c2 from t1 where c1 = p_i;
...
end;
$$ language plpgsql;
Run Code Online (Sandbox Code Playgroud)
根据doc,断开函数的唯一方法是RETURN.但这里的RETURN需要RETURN QUERY或RETURN NEXT - 似乎没有办法简单地退出该功能.
我想知道如何在函数内使用动态查询。我尝试了很多方法,但是,当我尝试编译我的函数时,会显示一条消息 SQL 42601。
我使用的代码:
CREATE OR REPLACE FUNCTION prc_tst_bulk(sql text)
RETURNS TABLE (name text, rowcount integer) AS
$$
BEGIN
WITH v_tb_person AS (return query execute sql)
select name, count(*) from v_tb_person where nome like '%a%' group by name
union
select name, count(*) from v_tb_person where gender = 1 group by name;
END
$$ LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)
我收到的错误消息:
ERROR: syntax error at or near "return"
LINE 5: WITH v_tb_person AS (return query execute sql)
Run Code Online (Sandbox Code Playgroud)
我尝试使用:
WITH v_tb_person AS (execute sql)
WITH v_tb_person …Run Code Online (Sandbox Code Playgroud) 我有一个Postgres功能:
create function myfunction(integer, text, text, text, text, text, text) RETURNS
table(id int, match text, score int, nr int, nr_extra character varying, info character varying, postcode character varying,
street character varying, place character varying, country character varying, the_geom geometry)
AS $$
BEGIN
return query (select a.id, 'address' as match, 1 as score, a.ad_nr, a.ad_nr_extra,a.ad_info,a.ad_postcode, s.name as street, p.name place , c.name country, a.wkb_geometry as wkb_geometry from "Addresses" a
left join "Streets" s on a.street_id = s.id
left join "Places" p …Run Code Online (Sandbox Code Playgroud) 当我更改底层函数时,在函数上构建的索引会发生什么?
说,我有一个函数clean_name()定义为:
CREATE OR REPLACE FUNCTION clean_name(n text)
RETURNS TEXT AS
$BODY$
DECLARE
rec TEXT;
BEGIN
EXECUTE
'SELECT Regexp_replace(' || quote_literal(n) || ', ''[a-z]'', '''', ''g'');'
INTO rec;
RETURN rec;
END;
$BODY$ LANGUAGE plpgsql IMMUTABLE
;
Run Code Online (Sandbox Code Playgroud)
然后创建一个索引:
CREATE INDEX my_table_upper_name_btree
ON schema.my_table USING GIST (my_text_field);
Run Code Online (Sandbox Code Playgroud)
但后来我决定重新定义函数来删除大写字母.我创建的索引会发生什么?它会自行改变吗?难道我DROP和CREATE一次?VACUUM [ANALYZE] [FULL]?
(有问题的功能是相似的,而是使用相当冗长的一系列替换,这些替换仍在调整但预计会保持稳定.)
我有8个类似的PL/pgSQL函数; 它们被用作INSTEAD OF INSERT/UPDATE/DELETE视图的触发器以使它们可写.每个视图组合了一个通用表的列(在下面的示例中称为"事物")和一个特殊表(下面的"shaped_things"和"flavored_things").顺便说一句,PostgreSQL的继承功能在我们的案例中不能使用.
触发器必须在通用表中插入/更新行; 这些部分在所有8个功能中是相同的.由于泛型表有大约30列,我试图在那里使用辅助函数,但是我无法将视图的NEW记录传递给需要things记录作为输入的函数.
(这里和这里都提出了类似的问题,但我不认为我可以在我的案例中应用建议的解决方案.)
CREATE TABLE things (
id SERIAL PRIMARY KEY,
name TEXT NOT NULL
-- (plus 30 more columns)
);
CREATE TABLE flavored_things (
thing_id INT PRIMARY KEY REFERENCES things (id) ON DELETE CASCADE,
flavor TEXT NOT NULL
);
CREATE TABLE shaped_things (
thing_id INT PRIMARY KEY REFERENCES things (id) ON DELETE CASCADE,
shape TEXT NOT NULL
);
-- etc...
Run Code Online (Sandbox Code Playgroud)
CREATE …Run Code Online (Sandbox Code Playgroud) 我正在玩PLV8来为PostgreSQL编写触发器和存储过程.到目前为止,与PLPGSQL相比,我并没有真正看到它的缺点.特别是如果使用JSON,它似乎比PLPGSQL更聪明.如果使用PLV8,是否存在已知的缺点或限制?PLV8可以完全替代PLPGSQL吗?如果有人可以分享他的经验,那就太好了.
我想PL/pgSQL通过psql命令行将参数传递给匿名块,然后在条件中检查该参数。
SQL 的相关部分在这里:
do $$
begin
if (':para' = 1) then
-- statements;
end if;
end $$
;
Run Code Online (Sandbox Code Playgroud)
我这样称呼这个脚本:
psql -d dbname -v para=1 < script.sql
Run Code Online (Sandbox Code Playgroud)
我收到错误:
ERROR: invalid input syntax for integer: ":para"
LINE 1: SELECT (':para' = 1)
^
QUERY: SELECT (':para' = 1)
CONTEXT: PL/pgSQL function inline_code_block line 3 at IF
Run Code Online (Sandbox Code Playgroud)
我尝试使用 case/when 范式,这也不起作用。
我猜psql参数与 PL/pgSQL 不兼容?最终,我的目标是,delete如果我1作为psql参数传递,则运行单个语句,如果传递0.
我已经看到有一些类似的问题已经退出,但是我还不了解如何自己编写代码。请记住,我只是该领域的初学者。
基本上我想像这样旋转表:
zoom | day | point zoom | 2015-10-01 | 2015-10-02 | ......
------+-----------+------- ---> ------+------------+-------------+
1 | 2015-10-01 | 201 1 | 201 | 685 |
2 | 2015-10-01 | 43 2 | 43 | 346 |
3 | 2015-10-01 | 80 3 | 80 | 534 |
4 | 2015-10-01 | 324 4 | 324 | 786 |
5 | 2015-10-01 | 25 5 | 25 | 685 |
1 | 2015-10-02 | 685
2 | 2015-10-02 …Run Code Online (Sandbox Code Playgroud) 我试着在下面的代码示例中模拟我的问题.在下面的代码中,我正在执行select * from test一个过程.我们知道,我们必须使用perform关键字.这非常有效:
perform * from test;
Run Code Online (Sandbox Code Playgroud)
但是,如果我尝试将该简单查询重写为CTE,我无法使其正常工作.我收到语法错误.
with test_as_cte as(select * from test) perform * from test_as_cte;
Run Code Online (Sandbox Code Playgroud)
这可能吗?什么是正确的语法?我尝试了几种替代方案并通过文档,但到目前为止没有任何成功.
(请注意,这只是解释我的问题的一个例子.我知道查询没有任何意义.)
create table test
(
key int primary key
);
create function test() returns trigger as
$$
begin
raise notice 'hello there';
-- this does work
perform * from test;
-- this doesn't work
with test_as_cte as(select * from test) perform * from test_as_cte;
return new;
end;
$$
language plpgsql;
create trigger test after insert on …Run Code Online (Sandbox Code Playgroud) 我从 Oracle 数据库转到 Postgres。我正在寻找的是如何打印PL/pgSQL中发生错误时的错误消息和行号?在 PL/SQL 中,有一个 DBMS_UTILITY.FORMAT_ERROR_BACKTRACE 命令用于此目的。
plpgsql ×10
postgresql ×10
dynamic-sql ×3
function ×2
bulkinsert ×1
crosstab ×1
database ×1
indexing ×1
null ×1
parameters ×1
plv8 ×1
psql ×1
triggers ×1