标签: plpgsql

pgsql返回表错误:列引用不明确

我一直得到这个错误:列引用"人"是模棱两可的.

我需要返回一个TABLE(人整数).当我使用SETOF整数时它工作正常但在这种情况下它不起作用.我的另一个函数recurse()非常好地返回一组整数.

CREATE OR REPLACE FUNCTION try(_group text) RETURNS TABLE (person integer) AS $$ 
DECLARE
     _init_id integer;
     _record integer;
BEGIN
     SELECT id INTO _init_id FROM egroups WHERE name = _group;

    FOR _record in SELECT person FROM egroupdata WHERE egroup IN (SELECT recurse(_init_id))
    LOOP
        RETURN NEXT;
    END LOOP;

END;
$$ language plpgsql stable;
Run Code Online (Sandbox Code Playgroud)

postgresql return function plpgsql

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

具有未知名称的PostgreSQL丢弃约束

我有一个SQL脚本需要删除几个约束并在最后恢复它们,但约束名称是自动生成的,并且每次运行脚本时都会有所不同.

我知道如何从表名中获取约束名称,但似乎不可能在drop语句中使用此信息.

select conname from pg_constraint where
   conrelid = (select oid from pg_class where relname='table name')
   and confrelid = (select oid from pg_class where relname='reference table');
Run Code Online (Sandbox Code Playgroud)

alter table something drop constraint (some subquery) 是语法错误.

理想情况下,我想得到约束名称并将其存储在一个变量中,但似乎Postgres不支持它,我不能使它与psql一起使用\set.

这甚至可能吗?

postgresql dynamic-sql plpgsql psql

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

postgresql 向下取半函数

PostgreSQL 中的 round(numeric,integer) 函数仅向上舍入:

round(cast (41.0255 as numeric),3) ==> 41.026
Run Code Online (Sandbox Code Playgroud)

由于我们需要一个返回 41.025 的 round 函数,并且(非常令人惊讶)PostgreSQL 中没有这样的函数(我们使用的是 9.1.5),因此我们编写了一个“包装器”函数,该函数在第一个版本中非常幼稚,并且粗糙......但由于 plpgsql 中缺乏对此类问题的本机支持,我们没有找到更好的东西。

代码如下所示。问题是它对于我们的目的来说太慢了。您能建议一个更好的方法来处理这项任务吗?

这是代码:

    CREATE OR REPLACE FUNCTION round_half_down(numeric,integer) RETURNS numeric 
    AS $$
    DECLARE
      arg ALIAS FOR $1;
      rnd ALIAS FOR $2;
      tmp1 numeric;
      res numeric;
    BEGIN
      tmp1:=arg;
      IF cast(tmp1 as varchar) ~ '5$'  THEN res:=trunc(arg,rnd);
      ELSE res:=round(arg,rnd);
      END IF;

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

我需要转换数值并使用正则表达式......这就是(我认为)破坏性能的原因。

正如您所知:我们需要这个,因为我们必须比较存储在两个不同列(在两个不同表上)但具有不同数字数据类型的数字:一个是双精度数,一个是实数。问题是,当插入到真实数据类型列时,PostgreSQL 执行 ROUND HALF DOWN,但它没有通过其数学函数提供这样的选项!

编辑:
该功能实际上有问题。第一次快速重写是为了提高工作功能的性能,但速度非常慢。

行为必须符合以下条件:
IF舍入时推迟的小数位向上<=5 => trunc
ELSE舍入。

一些例子: …

postgresql floating-point rounding plpgsql floating-accuracy

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

SELECT ... INTO的EXECUTE未实现

我试图在PostrgeSQL中运行此函数:

CREATE OR REPLACE FUNCTION create_partition_and_insert()
RETURNS trigger AS
$BODY$
DECLARE
partition VARCHAR(25);
_date text;
BEGIN
EXECUTE 'SELECT REPLACE(' || quote_literal(NEW.date) || ',''-'',''_'') into _date';
partition := TG_RELNAME || '_' || _date || ‘p’;
IF NOT EXISTS(SELECT relname FROM pg_class WHERE relname=partition) THEN
RAISE NOTICE 'A partition has been created %',partition;
EXECUTE 'CREATE TABLE ' || partition || ' (check (date = ''' || NEW.date || ''')) INHERITS (' || TG_RELNAME || ');';
END IF;
EXECUTE 'INSERT INTO ' || …
Run Code Online (Sandbox Code Playgroud)

postgresql triggers partitioning dynamic-sql plpgsql

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

如何在没有Active Record Model的情况下使用Active Model Serializer?

我想获取pl/pgsql函数的结果,该函数返回一组记录和用户AMS以序列化结果.我怎样才能做到这一点?

ruby-on-rails plpgsql pg active-model-serializers

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

将函数返回的记录拆分为多列

在基本的 Postgres 函数教程中,有一个带有OUT如下参数的示例:

create or replace function hi_lo(a numeric, 
                                 b numeric, 
                                 c numeric, 
                                 OUT hi numeric, 
                                 OUT lo numeric)
as $$
begin
hi := greatest(a, b, c);
lo := least(a, b, c);
end; $$
language plpgsql;
Run Code Online (Sandbox Code Playgroud)

然后结果看起来像

select hi_lo(2, 3, 4);
-- returns one column, "hi_lo" with value "(4, 2)".

select * from hi_lo(2, 3, 4);
-- returns two columns, "hi" / 4 and "lo" / 2.
Run Code Online (Sandbox Code Playgroud)

但是,假设您想要对执行联接的列执行该函数,并且您无权修改该函数或使用替代函数?例如,使用一些玩具数据:

select hi_lo(a.actor_id, length(a.name), ma.movie_id) 
from 
    actors a 
join 
    movies_actors ma …
Run Code Online (Sandbox Code Playgroud)

sql postgresql record plpgsql

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

循环遍历PL/pgSQL中给定的值列表

我正在尝试遍历几个字段并在它们上运行一个函数:

FOR field IN ARRAY['f1','f2'] LOOP
    execute pg_temp.converFieldToLower(newTableNameRaw,field)
END LOOP;
Run Code Online (Sandbox Code Playgroud)

这是我正在尝试使用的功能:

CREATE OR REPLACE FUNCTION pg_temp.converFieldToLower(t varchar, f varchar) RETURNS void AS $$
#variable_conflict use_variable
BEGIN
  EXECUTE concat_ws (' ', 'UPDATE',t,'SET',f,'= LOWER(',f,')');
END;
$$ LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)

看起来这不是声明数组的正确方法,我做错了什么?

ERROR:  syntax error at or near "ARRAY"
LINE 49:         FOR field IN ARRAY['f1','f2'] LOOP
Run Code Online (Sandbox Code Playgroud)

arrays postgresql loops plpgsql

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

PostgreSQL - 具有局部变量的函数 - 列引用不明确

我查看了与我的主题相匹配的其他问题,但就我而言,我认为歧义来自于与列同名的变量。

这是我尝试创建的函数的简化版本:

CREATE OR REPLACE FUNCTION get_user_id(username TEXT) 
RETURNS INTEGER AS $$
  DECLARE
    user_id BIGINT;
    other_param TEXT;
  BEGIN
    SELECT INTO user_id user_id FROM users WHERE users.username = get_user_id.username;

    SELECT INTO other_param users.value FROM users WHERE users.user_id = user_id;

    RETURN user_id;
  END
$$ LANGUAGE PLPGSQL 
Run Code Online (Sandbox Code Playgroud)

问题在于user_id右侧的WHERE被视为对该列的引用。

我肯定需要user_id一个局部变量,因为它将在函数中进一步使用UPDATE和DELETE操作,但我不会将其作为参数传递,而仅将用户名传递。

经过一些阅读并且之前也遇到过一些参数问题,我意识到我可以使用,get_user_id.username但它仅适用于参数,而不适用于局部变量(如果我将它与变量一起使用,则查询会失败,因为没有 FROM 子句get_user_id)。

因此,我是否遗漏了关于在函数内的查询中使用变量的一些(不太)明显的内容?

- - 编辑

抱歉,我过于简化了该功能,当然,有一个获取 user_id 的第一个查询,并且该部分工作正常。

postgresql plpgsql postgresql-9.5

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

PostgreSQL 中是否有临时表的替代方案来保存和操作结果集?

在 plpgsql 函数中,我需要保存 select 语句的结果集,并对该集执行许多后续查询和操作。

我读到有关 PostgreSQL 中的临时表的信息,但这些表在会话/事务范围内可见,而我需要我的表(或任何保存结果集的数据结构)在本地可见并且仅存在于函数内,以便每个函数调用都可以有自己的副本(表/数据结构)

我只需要一个类似表的结构来保存函数调用中的选择结果集,而不是临时表。有这样的事吗?

postgresql temp-tables plpgsql

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

如果 psql 函数和调用函数中存在则截断

我有以下代码来创建一个函数,web_channel2如果表不为空,则截断表中的所有行:

create or replace function truncate_if_exists(tablename text)
returns void language plpgsql as $$
begin
    select
    from information_schema.tables 
    where table_name = tablename;
    if found then
        execute format('truncate %I', tablename);
    end if;
end $$;
Run Code Online (Sandbox Code Playgroud)

不幸的是我不知道应该如何继续...如何执行该函数?

sql postgresql truncate plpgsql search-path

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