标签: plpgsql

错误:FOREACH 的循环变量必须是已知变量或变量列表

我的函数中几乎没有 FOREACH 循环。这些循环似乎与官方 postgresql 文档完全一致。返回此错误消息:

ERROR: loop variable of FOREACH must be a known variable or list of variables
SQL state: 42601
Run Code Online (Sandbox Code Playgroud)

谷歌没有找到任何关于postgresql "loop variable of FOREACH". 我以某种方式为我的旧 foreach 循环解决了这个问题,但我不记得如何解决,并且我找不到任何对于解决此错误可能重要的差异。

我在 Windows XP 32 位上有 PostgreSQL 9.3.4 和 pgAdmin III 1.18.1。以下是函数中有趣的部分:

CREATE OR REPLACE FUNCTION vloz_kont() RETURNS trigger AS $$
DECLARE
  _idmat integer;
  _nazmat text;
  _zast text;
  sj_nad text;
  ...
BEGIN

...

--bugged loop
FOREACH _mat IN ARRAY NEW._material::text[] LOOP
  SELECT split_part( _mat, ' ', 1 …
Run Code Online (Sandbox Code Playgroud)

postgresql plpgsql

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

函数使用两次时的 PL/pgSQL 问题(缓存问题?)

我面临一个绝对奇怪的问题,感觉更像是 Postgres 错误而不是算法问题。

我有这个功能:

CREATE FUNCTION sp_connect(mail character varying, passwd character varying, role character varying)
  RETURNS json LANGUAGE plpgsql STABLE AS
$$
DECLARE
    user_info record;
BEGIN
  IF role = 'Role1' THEN
    SELECT u.id, r.name INTO user_info
    FROM users u
    INNER JOIN users_roles ur ON ur.user_id = u.id
    INNER JOIN roles r ON ur.role_id = r.id
    WHERE u.email = mail
      AND u.password = encode(digest(CONCAT(passwd, u.password_salt), 'sha512'), 'hex')
      AND r.name = 'Role1';
  ELSIF role = 'Role2' THEN
    SELECT h.id, 'Role1' AS name …
Run Code Online (Sandbox Code Playgroud)

postgresql plpgsql functions plan-cache postgresql-9.4

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

如何在 PL/pgSQL EXCEPTION 块中重新引发异常?

考虑函数内的以下(不完整的)PL/pgSQL 块:

CREATE OR REPLACE FUNCTION my_calc(myvar1 NUMERIC, myvar2 NUMERIC)
    RETURNS NUMERIC
    RETURNS NULL ON NULL INPUT
    IMMUTABLE
    LANGUAGE plpgsql
    AS $$
    BEGIN
        RETURN some_third_party_function(myvar1, myvar2);
    EXCEPTION WHEN internal_error THEN
        IF SQLERRM LIKE 'KnownErrorPrefix:%' THEN
            RETURN 0;
        ELSE
            -- Reraise the original exception here
            RAISE EXCEPTION '%', SQLERRM;
        END IF;
    END
    $$
Run Code Online (Sandbox Code Playgroud)

当发生意外错误时,此代码将引发具有相同消息的新异常。但是,它不会保留原始类型或上下文。

如何重新引发或重新抛出未修改的原始异常?

postgresql exception plpgsql

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

Postgres 存储函数的自定义错误代码类和编号

我正在 Postgres 11.5 中编写一组存储函数,并且希望RAISE EXCEPTION在不满足各种先决条件时执行此操作。例如null需要一个字符串或者带字符串的空字符串,或者超出范围的整数参数等。

我可以RAISE EXCEPTION提供详细信息、提示和消息...但是错误代码应该使用什么范围?我检查了文档,但没有在这里找到任何指导:

https://www.postgresql.org/docs/11/errcodes-appendix.html

我在 StackOverflow 上搜索,发现几年前有一个类似的问题......但没有明确的答案。

是否有一些块或前缀可以安全或常规地用于从存储的函数/过程返回的自定义错误代码?

postgresql error-handling plpgsql

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

在 json/jsonb 行上使用 IS DISTINCT FROM 触发而不进行比较逐项?

当表具有 json 或 jsonb 列时,是否无法在 INSERT/UPDATE 触发器中进行全行比较?我收到的错误让我认为我需要单独比较每一列,因为该NEW.*/OLD.*格式不能用于比较 json 列。

CREATE OR REPLACE FUNCTION on_insert_update_modified()
RETURNS TRIGGER AS $$
BEGIN
  IF row(NEW.*) IS DISTINCT FROM row(OLD.*) THEN
    NEW.modified_at = now();
    RETURN NEW;
  ELSE
    RETURN OLD;
  END IF;
END;
$$ language 'plpgsql';

CREATE TRIGGER mytable_insert_update
BEFORE INSERT OR UPDATE ON mytable
FOR EACH ROW
EXECUTE PROCEDURE on_insert_update_modified();
Run Code Online (Sandbox Code Playgroud)

当我插入包含 json 和 jsonb 列的表时,出现以下错误:

CREATE OR REPLACE FUNCTION on_insert_update_modified()
RETURNS TRIGGER AS $$
BEGIN
  IF row(NEW.*) IS DISTINCT FROM row(OLD.*) THEN
    NEW.modified_at …
Run Code Online (Sandbox Code Playgroud)

postgresql trigger plpgsql json postgresql-9.6

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

plpgsql 函数中对记录列的动态访问

如何动态地从 plpgsql 函数中的记录中寻址一列?

在以下代码段中,我可以访问一个变量entity.colname,该变量包含应在 IF 控制结构中检查的列。我正在研究如何foobarentity.colname. 这在 plpgsql 中可能吗?

IF NEW.foobar IS NULL THEN
    RAISE EXCEPTION '% cannot be null', foobar;
END IF;
Run Code Online (Sandbox Code Playgroud)

这是可以但行不通的事情。

IF NEW.entity.colname IS NULL THEN
    RAISE EXCEPTION '% cannot be null', entity.colname;
END IF;
Run Code Online (Sandbox Code Playgroud)

上面的例子只是为了说明我想要实现的目标,不要判断功能。:)

我正在使用 PostgreSQL 9.1。

postgresql dynamic-sql plpgsql composite-types

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

使用 PL/pgSQL 在循环中运行 CTE 查询

我正在尝试执行使用 plpgsql 在循环中重复调用的查询 - 循环遍历另一个表(命名坐标),其中包含网格的左上角和右下角纬度/经度坐标,我传递左上角和右下角纬度/ 经度值输入我的 CTE,以便显示在给定两个时间戳的这些坐标内发出的请求量(每小时)-。但是,我无法显示 CTE 的结果,并且收到以下错误消息:

ERROR:  query has no destination for result data
HINT:  If you want to discard the results of a SELECT, use PERFORM instead.
CONTEXT:  PL/pgSQL function "inline_code_block" line 6 at SQL statement
Run Code Online (Sandbox Code Playgroud)

为了使整个查询根据需要工作,我应该在这里更改什么?我的代码如下:

DO $$
<<outer_scope>> DECLARE
  coords RECORD;
BEGIN
    FOR coords IN SELECT topleftlat, topleftlon, bottomrightlat, bottomrightlon FROM coordinates LOOP
        WITH cal AS (
        SELECT generate_series('2011-02-02 00:00:00'::timestamp ,
                   '2012-04-01 05:00:00'::timestamp , 
                   '1 hour'::interval) AS stamp
    ),
    qqq AS (
      SELECT date_trunc('hour', …
Run Code Online (Sandbox Code Playgroud)

postgresql plpgsql

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

如何访问PL/pgSQL中RETURNs累积的行数

表演时

RETURN QUERY ...
Run Code Online (Sandbox Code Playgroud)

在 PL/pgSQL 函数中,之后是否可以直接访问累积到记录堆中的行数,在函数结束时返回这些行数?

例子:

RETURN QUERY SELECT * FROM tableA; -- 14 records
RETURN QUERY SELECT * FROM tableB; -- 8 records
RETURN QUERY SELECT * FROM tableC; -- 22 records
Run Code Online (Sandbox Code Playgroud)

累积记录的数量现在应该是 44。

postgresql plpgsql functions

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

setof 类型或 setof 记录的串联

我在 Ubuntu 12.04 上使用 Postgresql 9.1。

在一个plpgsql函数中,我尝试连接setof从另一个函数返回的类型。

type pair_id_value问题的创建与create type pair_id_value as (id bigint, value integer);

返回基本的函数setof pair_id_value(稍后将被连接的那些)是这样的:

create or replace function compute_pair_id_value(id bigint, value integer)
    returns setof pair_id_value
as $$
    listResults = []
    for x in range(0,value+1):
        listResults.append({ "id": id, "value": x})
    return listResults
$$
language plpython3u;
Run Code Online (Sandbox Code Playgroud)

这个直截了当的 plpython 代码应该很好,例如查询:select * from compute_pair_id_value(1712437,2);返回很好:

  id            | value 
 ---------------+-----------
        1712437 |         0
        1712437 |         1
        1712437 |         2
 (3 rows) …
Run Code Online (Sandbox Code Playgroud)

postgresql stored-procedures plpgsql postgresql-9.1 set-returning-functions

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

我有一个 INSTEAD OF 触发器,但是当我插入视图时 PostgreSQL 仍然抱怨

我创建了一个视图和一个 INSTEAD OF 触发器,用于从该视图中插入/更新/删除。现在我尝试向视图中插入一些数据,PostgreSQL 返回以下错误(捷克语翻译:“chyba”=“error”,“Stav SQL”=“SQL state”):

ERROR:  cannot insert into view "ukaz_lok"
DETAIL:  Views that return columns that are not columns of their base relation are not automatically updatable.
HINT:  To enable inserting into the view, provide an INSTEAD OF INSERT trigger or an unconditional ON INSERT DO INSTEAD rule.
********** Chyba **********

ERROR: cannot insert into view "ukaz_lok"
Stav SQL: 55000
Run Code Online (Sandbox Code Playgroud)

这发生在其他一些 INSTEAD OF 触发器之前 - 这个错误只持续了一段时间(几个小时?我不记得了)然后 PostgreSQL 找到了触发器。我尝试了各种事情(更改触发器,删除所有触发器和视图并重新创建它们等),但我不确定什么有效,只是有些东西有效。那么究竟如何让 PostgreSQL 识别触发器呢?

我在 Windows XP 32 位上有 PostgreSQL …

postgresql trigger view plpgsql

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