标签: plpgsql

将函数动态应用到 Postgres 表中的所有列

使用 Postgres 13.1,我想对表的所有列应用前向填充函数。前向填充函数在我之前的问题中进行了解释:

但是,在这种情况下,列和表是指定的。我想获取该代码并将其应用于任意表,即。指定一个表,并将前向填充应用于每一列。

以此表为例:

CREATE TABLE example(row_num int, id int, str text, val integer);
INSERT INTO example VALUES
  (1, 1, '1a', NULL)
, (2, 1, NULL,    1)
, (3, 2, '2a',    2)
, (4, 2, NULL, NULL)
, (5, 3, NULL, NULL)
, (6, 3, '3a',   31)
, (7, 3, NULL, NULL)
, (8, 3, NULL,   32)
, (9, 3, '3b', NULL)
, (10,3, NULL, NULL)
;
Run Code Online (Sandbox Code Playgroud)

我从该函数的以下工作基础开始。我称之为传递一些变量名。请注意,第一个是表名而不是列名。该函数获取表名并创建所有列名的数组,然后输出名称。

create or replace function col_collect(tbl text, …
Run Code Online (Sandbox Code Playgroud)

sql postgresql null dynamic-sql plpgsql

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

PostgreSQL自定义异常?

在Firebird中,我们可以声明自定义异常,如下所示:

CREATE EXCEPTION EXP_CUSTOM_0'异常:自定义异常';

这些都存储在数据库级别.在存储过程中,我们可以像这样引发异常:

EXCEPTION EXP_CUSTOM_0;

PostgreSQL中有相同的东西吗?

postgresql exception plpgsql

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

错误:类型"执行"不存在

我正在尝试编写一个PL/PgSQL函数,它将执行存储在PostgreSQL表中的查询,如下所示:

CREATE OR REPLACE FUNCTION evaluate_scenario(scenario_id int)
RETURNS TABLE(line_item_id int, organization_id int, data_element_id int, value varchar) AS $$
BEGIN
  RETURN QUERY
  SELECT
    li.id,
    li.organization_id,
    de.id,
    (EXECUTE 'SELECT ' || de.query)::varchar
  FROM
    line_items AS li INNER JOIN
    summary_files AS sf ON li.summary_file_id = sf.id INNER JOIN
    scenarios AS s ON s.summary_file_id = sf.id CROSS JOIN
    data_elements AS de
  WHERE
    s.id = 1 AND
    de.scope = 3 AND (
      de.model_id = s.model_id OR
      de.scenario_id = s.id OR
      de.organization_id = s.organization_id
    );
END; …
Run Code Online (Sandbox Code Playgroud)

postgresql plpgsql

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

更新后使用触发器更新表

我有两张桌子

 batch (batch_id,start_date,end_date,batch_strength,is_locked)
 sem (user_id,is_active,no_of_days)
Run Code Online (Sandbox Code Playgroud)

我已经执行了下面给出的触发器过程,然后使用查询更新表

CREATE OR REPLACE FUNCTION em_batch_update()
  RETURNS trigger AS $em_sem_batch$
BEGIN

UPDATE batch set is_locked='TRUE'
where (start_date
       + (select no_of_days from sem
          WHERE is_active='TRUE' and user_id='OSEM')
      ) <= current_date;

return NEW;

END;
$em_sem_batch$  LANGUAGE plpgsql;

CREATE TRIGGER em_sem_batch
BEFORE UPDATE ON batch FOR EACH ROW EXECUTE PROCEDURE em_batch_update();

update em_batch set batch_strength=20 where batch_id='OD001C001B3';
Run Code Online (Sandbox Code Playgroud)

发生了错误:

错误:超出堆栈深度限制
提示:确保平台的堆栈深度限制足够后,增加配置参数"max_stack_depth"(当前为2048kB).

postgresql triggers plpgsql sql-update postgresql-9.1

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

函数返回"查询没有结果数据的目的地"

我正在尝试创建一个有效地充当UPSERT的函数,并返回0表示成功的UPDATE或者返回成功INSERT的新记录的id.虽然该函数将成功创建,但当我尝试运行它时会出现以下错误:

query has no destination for result data
Run Code Online (Sandbox Code Playgroud)

我正在以这种方式运行它(数据显然是掩盖的):

select public.mergeaddress(0, 2, 'XXX XX XXXX', 'XXXX', 'XX', 'XXXXX', true, true, -XXX.XXXXXX, XX.XXXXXXX);
Run Code Online (Sandbox Code Playgroud)

我知道我必须在这里遗漏一些明显的东西.有什么想法吗?

CREATE FUNCTION mergeAddress(integer, integer, varchar, varchar, varchar, varchar, boolean, boolean, float, float) RETURNS integer AS

$$

DECLARE new_id integer;

BEGIN
    LOOP
        UPDATE users_addresses SET users_id = $2, address_street = $3, address_city = $4, address_state = $5, address_zip = $6, is_private = $7, is_default = $8, long = $9, lat = $10 WHERE id = $1 RETURNING id; …
Run Code Online (Sandbox Code Playgroud)

postgresql plpgsql postgresql-9.1

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

返回类型的简单方法是SETOF表加上其他字段?

我正在编写一个PL / pgSQL存储过程,该过程将返回一组记录。每个记录都包含现有表的所有字段(将其称为Retailer,该字段具有两个字段:retailer_key和retailer_name)。这当然有效:

CREATE FUNCTION proc_Find_retailers
 (IN p_Store_key INT)
   RETURNS SETOF Retailer
   AS $$ ...`
Run Code Online (Sandbox Code Playgroud)

现在,我想更新sp,以便它在每个返回的记录的'end'处返回另外两个字段。我可以做一些事情,例如:

CREATE FUNCTION proc_Find_store
 (IN p_Store_key INT)
   RETURNS TABLE (
      retailer_key int,
      retailer_name varchar(50),
      addl_field_1 int,
      addl_field_2 double precision)
   AS $$ ...
Run Code Online (Sandbox Code Playgroud)

在现实世界中,我的Retailer表具有50个字段(在我的示例中没有这两个字段),因此枚举RETURNS TABLE子句中的所有这些字段很繁琐。有没有捷径可走,所以我可以这样说:(我意识到我在这里编造的东西在语法上是非法的,但我这样做是为了让您有我所寻找的味道):

CREATE FUNCTION proc_Find_store
 (IN p_Store_key INT)
   RETURNS (SETOF Store,
      addl_field_1 int,
      addl_field_2 double precision)
   AS $$ ...
Run Code Online (Sandbox Code Playgroud)

postgresql plpgsql composite-types postgresql-9.2

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

如何使PostgreSQL函数成为原子?

假设我有一些PostgreSQL函数,如下所示:

CREATE FUNCTION insertSth() RETURNS void AS $$
BEGIN
    INSERT INTO ...;
END;

CREATE FUNCTION removeSthAfterSelect() RETURNS TABLE(...) AS $$
BEGIN
     SELECT id INTO some_id ...;
     RETURN QUERY SELECT * FROM ...;
     DELETE FROM ... WHERE id = some_id;
END;

CREATE FUNCTION justDeleteSth() RETURNS void AS $$
BEGIN
     DELETE FROM ...;
END;

CREATE FUNCTION justSelectSth() RETURNS TABLE(...) AS $$
BEGIN
     RETURN SELECT * FROM ...;
END;
Run Code Online (Sandbox Code Playgroud)

从我对PostgresSQL函数的理解insertSth,justDeleteSth并将justSelectSth以原子方式执行(?).所以并行执行它们不会搞砸任何东西.

但是,removeSthAfterSelect如果有并行执行,它可能会SELECT id INTO some_id …

sql postgresql stored-procedures plpgsql psql

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

plpgsql - 在declare语句中使用动态表名

我正在尝试编写plpgsql以下形式的函数(注意这是一个简化版本):

CREATE FUNCTION check_valid(tablename regclass) RETURNS boolean AS $$

DECLARE valid_row tablename%ROWTYPE;

BEGIN

EXECUTE format('SELECT * FROM %s', tablename) into valid_row;

IF valid_row IS NULL THEN
      RETURN QUERY SELECT false;

ELSIF valid_row.is_valid = false;
      RETURN QUERY SELECT false;

ELSIF valid_row.hit_count > valid_row.hit_limit;
      RETURN QUERY SELECT false;

ELSE
      RETURN QUERY SELECT true;

END IF;

END

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

失败的部分是DECLARE线.如何根据变量表名声明类型?或许我需要以某种方式施展它?

类似的DECLARE mytable%ROWTYPE;工作正常,但如果我使用变量名称,如tablename%ROWTYPE:

ERROR: relation "tablename" does not exist

sql postgresql plpgsql

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

如何在PL/pgSQL中按行类型返回表

我正在尝试使用PL/pgSQL(PostgreSQL 9.3)实现一个函数,该函数返回一个与参数中的输入表具有相同结构的表.基本上,我想更新一个表,并使用plpgsql返回更新表的副本.我在SO周围搜索并发现了几个相关的问题(例如,返回动态表,其中包含来自PL/pgSQL函数的未知列和表名作为PostgreSQL函数参数),这导致了以下最小测试示例:

CREATE OR REPLACE FUNCTION change_val(_lookup_tbl regclass)
RETURNS _lookup_tbl%rowtype AS --problem line
$func$
BEGIN
    RETURN QUERY EXECUTE format('UPDATE %s SET val = 2 RETURNING * ; ', _lookup_tbl);
END
$func$ LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)

但我不能拿过去给正确的返回类型TABLE或SETOF RECORD在problem line.根据这个答案:

SQL要求在调用时知道返回类型

但我认为返回类型(我打算从输入表类型中借用)是已知的.有人可以帮助解释是否可以修复上述PL/pgSQL函数的签名?

注意,我需要参数化输入表并返回该表的更新.欢迎替代方案.

postgresql polymorphism dynamic-sql plpgsql

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

如何在触发函数中将OLD,NEW和标识符传递给EXECUTE?

我正在开始尝试新数据库中的一些东西,并遇到了问题.我是PostgreSQL的新手.

我正在尝试在users表的列中创建值的更改历史记录.这个想法很简单.每当有更新时,都会在另一个表(代表历史记录)中插入新记录.

DROP FUNCTION IF EXISTS LOCA_APP.FUNC_HISTORICO_MOD_USUARIOS() CASCADE;
CREATE OR REPLACE FUNCTION LOCA_APP.FUNC_HISTORICO_MOD_USUARIOS() RETURNS TRIGGER
AS $$ 
BEGIN
    EXECUTE 'INSERT INTO LOCA_APP.TB_MODIFICACOES (
        MOD_MOMENTO ,             -- Translated to: Moment
        MOD_VALOR_ANTERIOR ,      -- Translated to: Old value
        MOD_VALOR_ATUAL ,         -- Translated to: New value
        MOD_USUARIO ,             -- Translated to: User (ID)
        MOD_DADO)                 -- Translated to: Data (Column Name - ID)
    VALUES(
        now() , 
        OLD.' || TG_ARGV[0] || ' , 
        NEW.' || TG_ARGV[0] || ' , 
        '|| TG_RELID || ' ,
        (SELECT …
Run Code Online (Sandbox Code Playgroud)

database postgresql triggers dynamic-sql plpgsql

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