标签: plpgsql

我的美元符号未终止

我想创建一个如下所示的函数,它根据给定的输入插入数据。但我不断收到有关未确定的美元符号的错误。

CREATE OR REPLACE FUNCTION test_generate 
(
  ref         REFCURSOR,
  _id      INTEGER
)
RETURNS refcursor AS $$
DECLARE
    BEGIN
        DROP TABLE IF EXISTS test_1;
        CREATE TEMP TABLE test_1 
        (
            id int,
            request_id int,
            code text
        );

        IF _id IS NULL THEN
            INSERT INTO test_1
            SELECT
                rd.id, 
                r.id, 
                rd.code 
            FROM 
                test_2 r
            INNER JOIN 
                raw_table rd 
            ON 
                rd.test_2_id = r.id
            LEFT JOIN 
                observe_test o 
            ON 
                o.raw_table_id = rd.id
            WHERE o.id IS NULL 
            AND COALESCE(rd.processed, 0) = 0;
        ELSE
            INSERT INTO test_1
            SELECT …
Run Code Online (Sandbox Code Playgroud)

postgresql plpgsql

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

PL/pgSQL 行到 json 数组

我正在尝试检索包含此函数返回的行的 json 数组:

CREATE OR REPLACE FUNCTION get_users_list() 
RETURNS TABLE (
id INTEGER,
name VARCHAR,
surname VARCHAR,
fkrole INTEGER,
username VARCHAR
) as $$
BEGIN

RETURN QUERY SELECT users.id, users.name,
                    users.surname, users.fkrole, 
                    users.username 
FROM users;
END;
$$ LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)

谁能给我提示吗?如何将多行转换为单个 JSON 数组?

谢谢!

postgresql stored-procedures plpgsql

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

如何在触发函数中选择多个变量?

这就是我想要实现的目标:

CREATE FUNCTION f() RETURNS trigger AS $$
  BEGIN
    SELECT COUNT(*) AS total_num, SUM(width) AS total_width
    FROM some_table WHERE foo = NEW.foo;
    IF total_num > 0 AND total_width > 100
    THEN
      RAISE EXCEPTION 'this is bad';
    END IF;
    RETURN NEW;
  END;
$$ LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)

但它在语法上还不正确。

我读过我首先需要DECLARE变量(在本例中total_num为 和total_width),以便我可以使用它们并使用SELECT INTO,但我见过SELECT仅包含单个变量/语句的示例。如果我有更多怎么办?

postgresql plpgsql database-trigger

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

FOREACH 循环的 PostgreSQL PL/pgSQL 语法错误

我正在尝试通过编写一些简单的程序来学习 PL/pgSQL。为了了解 FOREACH 循环,我编写了以下内容:

CREATE OR REPLACE FUNCTION test(int[]) RETURNS void AS $$  
DECLARE                                                     
    window INT;                                             
BEGIN                                                       
    FOREACH window IN ARRAY $1                              
    LOOP                                                    
        EXECUTE 'SELECT $1' USING window;                   
    END LOOP;                                               
$$ LANGUAGE plpgsql;                                        

SELECT test(ARRAY [30,60]);    
Run Code Online (Sandbox Code Playgroud)

我希望该代码片段首先打印30,然后打印60。但是,我收到以下错误。

psql:loop.sql:11: ERROR:  syntax error at end of input
LINE 7:         EXECUTE 'SELECT $1' USING window;
                                                ^
psql:loop.sql:13: ERROR:  function test(integer[]) does not exist
LINE 1: SELECT test(ARRAY [30,60]);
               ^
HINT:  No function matches the given name and argument types. …
Run Code Online (Sandbox Code Playgroud)

postgresql plpgsql

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

PL/pgSQL“for 循环”+ select 基本示例(“hello world”)

我使用 Postgres 一段时间了,但对 PL/pgSQL 完全陌生。

\n\n

我正在努力让基本的for 循环发挥作用。

\n\n

这工作正常:

\n\n
-- Without SELECT\nDO $$\nBEGIN \n  FOR counter IN 1..6 BY 2 LOOP\n    RAISE NOTICE 'Counter: %', counter;\n  END LOOP;\nEND; $$;\n
Run Code Online (Sandbox Code Playgroud)\n\n

但我真正想要的是迭代查询的结果SELECT

\n\n

我一直遇到这个错误:

\n\n
\n

查询错误:错误:行循环的循环变量必须是记录或行变量或标量变量列表

\n
\n\n

对我来说听起来很晦涩,谷歌搜索也没有帮助。

\n\n

我想使用我自己的数据中的一个表(我希望使用 a SELECT * FROM mytable WHERE \xe2\x80\xb9whatever\xe2\x80\xba),但我意识到我什至无法让for 循环处理更简单的 data

\n\n

拿着它:

\n\n
-- with a SELECT\nDO $$\nBEGIN \nRAISE NOTICE 'Get ready to be amazed\xe2\x80\xa6';\nFOR target IN …
Run Code Online (Sandbox Code Playgroud)

postgresql plpgsql

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

PostgreSQL 中的“SELECT INTO”多个变量

我在一次分配多个变量时遇到问题。运行下面的代码

SELECT v1, v2 INTO x, y FROM (VALUES (1, 2)) AS t (v1, v2);
Run Code Online (Sandbox Code Playgroud)

抛出错误:

错误:“,”处或附近存在语法错误 第 1 行:从 (values (1,2)) as t (v1, v2) 选择 v1, v2 into x, y;

链接到dbfiddle:

https://dbfiddle.uk/?rdbms=postgres_11&fiddle=98285b190de7871354ccb444d17eb25f

有人可以帮忙吗?

谢谢。

sql database postgresql plpgsql select-into

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

PostgreSQL `IS NOT NULL` 对于复合类型无法正常工作

我正在尝试创建一个函数,该函数应该将表行映射到我的用户定义类型(这是复合类型)并返回结果。如果该表中的某些列为 NULL,则IS NOT NULL检查我的自定义类型不起作用!

例子

我有一个简单的复合类型:

CREATE TYPE my_custom_type AS (
  sender VARCHAR(30),
  destination VARCHAR(30),
  count INTEGER
);
Run Code Online (Sandbox Code Playgroud)

还有一张桌子:

CREATE TABLE messages (
  id INTEGER PRIMARY KEY,
  sender VARCHAR(30),
  destination VARCHAR(30),
  count INTEGER
);
Run Code Online (Sandbox Code Playgroud)

在此示例中插入单行:

INSERT INTO messages VALUES (1, 'sender', 'destination', 100);
Run Code Online (Sandbox Code Playgroud)

现在我想创建一个函数,它将将该行作为自定义 Postgres 类型返回:

CREATE OR REPLACE FUNCTION my_custom_function() 
RETURNS my_custom_type AS
$$
DECLARE
    result my_custom_type;
BEGIN

    SELECT sender, destination, count
    FROM messages
    LIMIT 1
    INTO result;

    IF result IS NULL THEN
        RAISE EXCEPTION 'no data'; …
Run Code Online (Sandbox Code Playgroud)

postgresql plpgsql composite-types sql-null

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

在 PL/pgSQL 函数中分割逗号分隔的字符串

我正在尝试编写一个函数,该函数将 ID 作为输入并更新该给定 ID 上的一些字段。到目前为止,它看起来像这样:

CREATE FUNCTION update_status(p_id character varying,
                              p_status character varying DEFAULT NULL::character varying) RETURNS character varying
    LANGUAGE plpgsql
AS
$$
DECLARE
    v_row_count bigint DEFAULT 0;
    v_result    varchar(255);
BEGIN
    
    IF p_id IS NOT NULL THEN
        SELECT count(user_id)
        INTO v_row_count
        FROM test
        WHERE user_id = p_id;
    END IF;

    IF v_row_count <= 0 THEN
        v_result = 'User not found';
        RETURN v_result;

    ELSE
        IF p_id NOT LIKE '%,%' THEN
            UPDATE test
            SET status     = p_status,
                updated_by = 'admin'
            WHERE user_id IN …
Run Code Online (Sandbox Code Playgroud)

sql postgresql plpgsql

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

Postgresql - 将字符串与空值进行比较

我有点困惑,因为我相信这个问题的答案相当简单,但我搜索并尝试了多种选择,但找不到正确的答案。

数据库是PostgreSQL 13.1

我正在使用一个 API,它将 JSON 对象发送到数据库中的存储函数,如下所示:

select * from api.car_model_create( '{
  "payload": {
    "manufacturer": "ai3ZV7PzbP5dNo2fb9q9QGjj2nS5aWJm",
    "name": "SR22",
    "variant": "G2",
    "subname": null
},
    "stk": "YbtmjypXMqXb1U5WOq53DxkaxrbIxl4X"
}'::json
);
Run Code Online (Sandbox Code Playgroud)

该函数查询具有以下结构的表:

CREATE TABLE app.car_models (
   id INTEGER NOT NULL
   , public_id CHARACTER(32) DEFAULT (api.random_string(32))
   , name CHARACTER VARYING(64) NOT NULL
   , variant CHARACTER VARYING(64)
   , subname CHARACTER VARYING(64)
   , designator CHARACTER VARYING(16)
   , manufacturer INTEGER NOT NULL
   , car_type INTEGER 
   , status INTEGER NOT NULL DEFAULT 1
) WITHOUT OIDS TABLESPACE app;
Run Code Online (Sandbox Code Playgroud)

函数内部是这样的查询: …

sql postgresql plpgsql sql-null

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

PL/pgSQL 循环不更新当前时间戳/now()

我想看看 postgres 中 DO 块内的循环迭代需要多长时间。基本布局如下:

DO $$
declare v_time timestamptz;
declare i record;
begin
for i in select generate_series(1, 5) t
loop

select current_timestamp into v_time;

perform pg_sleep(i.t);
-- something done here (pg_sleep to ensure some time passes)

raise notice '%', v_time - (select current_timestamp);
-- expect negative interval from RAISE. 
end loop;
end; $$;
Run Code Online (Sandbox Code Playgroud)

但是,当我运行此命令时(已在 Postgres 13 和 9 上尝试过),我得到返回 0S 的间隔:

NOTICE:  00:00:00
NOTICE:  00:00:00
NOTICE:  00:00:00
NOTICE:  00:00:00
NOTICE:  00:00:00
DO

Query returned successfully in 15 secs …
Run Code Online (Sandbox Code Playgroud)

postgresql plpgsql

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