标签: plpgsql

如何从INSERT/UPDATE规则(触发器)执行的函数返回记录?

为我的数据库执行以下方案:

create sequence data_sequence;

create table data_table
{
    id integer primary key;
    field varchar(100);
};

create view data_view as
select id, field from data_table;

create function data_insert(_new data_view) returns data_view as
$$declare
    _id integer;
    _result data_view%rowtype;
begin
    _id := nextval('data_sequence');
    insert into data_table(id, field) values(_id, _new.field);
    select * into _result from data_view where id = _id;
return _result;
end;
$$
language plpgsql;

create rule insert as on insert to data_view do instead
select data_insert(new);
Run Code Online (Sandbox Code Playgroud)

然后输入psql:

insert into data_view(field) values('abc');
Run Code Online (Sandbox Code Playgroud)

想看到类似的东西: …

sql postgresql triggers stored-procedures plpgsql

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

在postgres(plpgsql)中,如何创建一个在变量table_name上返回select*的函数?

基本上,至少为了概念验证,我想要一个我可以运行的函数:SELECT res('table_name'); 这将给我SELECT*FROM table_name;的结果.我遇到的问题是架构......在我所拥有的函数的声明中:

创建或替换功能res(table_name TEXT)返回设置此THEPISEPEPROBLEM AS

问题是我不知道如何声明我的返回,因为它要我指定一个表或一个模式,在实际运行该函数之前我不会这样做.

有任何想法吗?

postgresql plpgsql

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

Postgresql 返回 setof 记录

我有一个自定义类型:

create type some_type as (
    some_bool_param     boolean, 
    str                 varchar
);
Run Code Online (Sandbox Code Playgroud)

我用这种类型的字段创建一个表并插入一些数据:

create table test_table (
    strs some_type
);

insert into test_table(strs) values
  ((false, 'First str'))
, ((false, 'Second str '))
, ((false, 'Third str'))
, ((false, 'Yet another str'));
Run Code Online (Sandbox Code Playgroud)

现在我尝试返回 setofsome_type数据:

create or replace function get_str() returns setof some_type as
$$
declare
    r some_type;
begin
    for r in 
        select * from test_table loop
    return next r;
    end loop;
    return;
end;
Run Code Online (Sandbox Code Playgroud)

我打电话get_str()

select * from get_str(); …
Run Code Online (Sandbox Code Playgroud)

postgresql select boolean row plpgsql

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

用于INSERT多个表中的动态列列表的函数

我想在PostgreSQL中做这样的事情.

我试过这个:

CREATE or replace FUNCTION create_patient(_name text, _email text, _phone text
     , _password text
     , _field1 text, _field2 text, _field3 timestamp, _field4 text
     , OUT _pid integer, OUT _id integer
    ) RETURNS record AS
$$
DECLARE
    _id integer;
    _type text;
    _pid integer;
BEGIN
    _type := 'patient';

    INSERT into patients (name, email, phone, field1, field2, field3)
    VALUES (_name, _email, _phone, _field1, _field2, _field3)
    RETURNING id into _pid;

    INSERT into users (username, password, type, pid, phone, language)
    VALUES (_email, …
Run Code Online (Sandbox Code Playgroud)

postgresql stored-procedures insert plpgsql postgresql-9.1

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

我们可以在plpgsql函数的开始结束块中声明变量吗?

我试着编写简单的函数:

CREATE OR REPLACE FUNCTION add_mail_settings_column() RETURNS void AS $$
BEGIN
    asd text := 'asd';
END $$ 
LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)

但它不起作用:

ERROR:  syntax error at or near "asd"
LINE 3:  asd text := 'asd';
Run Code Online (Sandbox Code Playgroud)

但如果我按如下方式移动它:

CREATE OR REPLACE FUNCTION add_mail_settings_column() RETURNS void AS $$
DECLARE
    asd text := 'asd';
BEGIN

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

它工作正常.那么我们不能把变量声明放到函数体中吗?

sql postgresql plpgsql

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

PL/pgSQL 函数的输入表

我想使用带有表和几列的 plpgsql 函数作为输入参数。这个想法是将表格分成块,并对每个部分做一些事情。

我尝试了以下功能:

CREATE OR REPLACE FUNCTION my_func(Integer)
  RETURNS SETOF my_part
AS $$
DECLARE
out my_part;
BEGIN
  FOR i IN 0..$1 LOOP
    FOR out IN
    SELECT * FROM my_func2(SELECT * FROM table1 WHERE id = i)
    LOOP
       RETURN NEXT out;
   END LOOP;
  END LOOP;
  RETURN;
END;
$$
LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)

my_func2() 是在每个较小的部分上做一些工作的函数。

CREATE or REPLACE FUNCTION my_func2(table1) 
  RETURNS SETOF my_part2 AS
$$ 
BEGIN
RETURN QUERY
SELECT * FROM table1;
END
$$
LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)

如果我运行:

SELECT * FROM my_func(99);
Run Code Online (Sandbox Code Playgroud)

我想我应该收到为每个 ID …

sql postgresql plpgsql

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

在创建角色上创建触发器

我有一个 PostgreSQL 数据库。我创建新的只读用户如下:

$ sudo -upostgres psql postgres
postgres=# CREATE ROLE readonly;
postgres=# GRANT SELECT ON ALL TABLES IN SCHEMA public TO readonly;
postgres=# BEGIN;
postgres=# CREATE ROLE "<PUT_READONLY_USERNAME_HERE>" WITH LOGIN ENCRYPTED PASSWORD '<USE_A_NICE_STRONG_PASSWORD_PLEASE' IN ROLE readonly;
postgres=# COMMIT;
Run Code Online (Sandbox Code Playgroud)

我还有一个表“is_admin”,我在其中手动添加新用户(这种情况很少发生)。如果它是只读用户users.is_admin = false并且它是具有所有特权的用户users.is_admin = true.

   users.oid users.is_admin (bool)
       1 真
       2 假
       3 假
      ……

然后在代码中,我使用此查询检查用户是否为管理员:

SELECT users.is_admin
FROM users.users
JOIN pg_authid ON pg_authid.oid = users.oid::oid
WHERE rolname = "PUT_ROLNAME";
Run Code Online (Sandbox Code Playgroud)

那么,主要问题是如何自动将新用户添加到“is_admin”表中?我读过那个触发器或类似的东西可以帮助我(例如,触发器 ON CREATE ROLE)。

postgresql triggers plpgsql

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

Postgres 中的删除函数

我有以下功能:

CREATE FUNCTION "updateStat"(_request_date timestamp without time zone, _calls integer, _latency integer) RETURNS void AS $$
BEGIN
  LOCK TABLE "statistics" IN SHARE ROW EXCLUSIVE MODE;
  WITH upsert AS (UPDATE "statistics" set calls = calls + _calls, total_latency = total_latency + _latency WHERE request_date=_request_date RETURNING request_date)
  INSERT INTO "statistics" ("request_date", "calls", "total_latency") SELECT _request_date, _calls, _latency WHERE NOT EXISTS (SELECT "request_date" FROM upsert);
END;
$$ LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)

我怎样才能放弃这样的功能?

我尝试了以下方法:

# DROP FUNCTION updateStat(void);
ERROR:  function updatestat(void) does not exist
# DROP …
Run Code Online (Sandbox Code Playgroud)

sql postgresql plpgsql identifier sql-function

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

Postgres 从当前插入创建触发器传递参数

我对 Postgres 非常陌生,现在我的任务是创建一个在插入后触发的触发器。基本上,我会让脚本执行插入操作,触发触发器,该触发器会根据 Insert 语句中的参数从另一个表中抓取一个字段,然后使用另一个表中的值更新新插入的记录。

  1. INSERT 记录到表 1。
INSERT INTO "TableA" VALUES ('ABC-101', 'John Doe', '')

PersonID  |  Name  |  Address
------------------------------
ABC-101    John Doe 
Run Code Online (Sandbox Code Playgroud)
  1. 在此插入之后,我将触发触发器,该触发器将从 TableB 中的字段中获取值。
CREATE OR REPLACE FUNCTION fn_getaddress()
  RETURNS trigger AS
$BODY$
DECLARE
  PersonID     TEXT;
BEGIN
  PersonID  := TG_ARGV[0];

    UPDATE  "TableA" 
       SET  "Address"  = (SELECT  "Address" 
                            FROM  "TableB" 
                           WHERE  "PersonID" = PersonID);
    RETURN null;
END;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
Run Code Online (Sandbox Code Playgroud)

这是我的触发器:

CREATE TRIGGER tr_getaddress
AFTER INSERT
ON TableA
FOR EACH ROW
EXECUTE PROCEDURE fn_getaddress(personid); …
Run Code Online (Sandbox Code Playgroud)

postgresql triggers function plpgsql

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

RETURN不能将参数与OUT参数一起使用

我做了从oracle到pgsql的数据库迁移,并得到了如下代码:

CREATE OR REPLACE FUNCTION PKG_UTIL_BD_LOGISTICS_getsignerinfo (
  i_opCode T_MQ_LOGIC_TRACK_HEAD_LOG.LP_CODE%TYPE, i_remark T_MQ_LOGIC_TRACK_HEAD_LOG.REMARK%TYPE, i_acceptTime T_MQ_LOGIC_TRACK_HEAD_LOG.SIGNED_TIME%TYPE, i_signer T_MQ_LOGIC_TRACK_HEAD_LOG.SIGNER%TYPE, i_lpcode T_MQ_LOGIC_TRACK_HEAD_LOG.LP_CODE%TYPE,
  o_signer OUT T_MQ_LOGIC_TRACK_HEAD_LOG.SIGNER%TYPE, o_signerTime OUT T_MQ_LOGIC_TRACK_HEAD_LOG.SIGNED_TIME%TYPE, o_status OUT T_MQ_LOGIC_TRACK_HEAD_LOG.STATUS%TYPE ) 
RETURNS RECORD AS $body$
DECLARE

  v_signer        T_MQ_LOGIC_TRACK_HEAD_LOG.SIGNER%TYPE;
  v_signerTime    T_MQ_LOGIC_TRACK_HEAD_LOG.SIGNED_TIME%TYPE;
  v_status        T_MQ_LOGIC_TRACK_HEAD_LOG.STATUS%TYPE;

BEGIN
IF i_lpcode = 'SF' THEN
   IF i_opCode = '8000' THEN
      IF POSITION('?back' in i_remark) > 0 THEN
        v_status := '3';
      ELSE
        v_status := '7';
        v_signerTime := i_acceptTime;
        v_signer := SUBSTR(i_remark, POSITION('?' in i_remark) + 1);
      END IF;
  ELSIF i_opCode = '9999' …
Run Code Online (Sandbox Code Playgroud)

database postgresql plpgsql

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