标签: plpgsql

为什么我在批处理从Java上执行PostgreSQL上的存储过程时收到错误通知"结果不被预期"?

我在数据库中有这个过程:

CREATE OR REPLACE FUNCTION replacePageRelevance(id INT, value REAL) RETURNS VOID AS $$
BEGIN
INSERT INTO pageRelevance VALUES (id,value);
EXCEPTION WHEN unique_violation THEN
    UPDATE pageRelevance SET relevance = value WHERE pageId = id;       
END
$$
LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)

这段代码调用了这个函数:

private final String PAGE_RELEVANCE_SQL = "SELECT replacePageRelevance(?,?::REAL)";
try (CallableStatement cstm = conn.prepareCall(PAGE_RELEVANCE_SQL)) {
        for (Map.Entry<Integer, Double> entry : weightMap.entrySet()) {
            cstm.setInt(1, entry.getKey());
            cstm.setDouble(2, entry.getValue());
            cstm.addBatch();
        }
        cstm.executeBatch();
    } catch (SQLException e) {
        LOGGER.error("Error discovering pages relevance: " + e.getNextException());
    }
}
Run Code Online (Sandbox Code Playgroud)

当我执行批处理时,会在表中插入或替换值,但在此之后,我收到一个异常通知 …

java postgresql stored-procedures plpgsql

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

通过循环在[0,1001]中生成随机数的非重复随机数

我需要在plpgsql中生成一个随机数的非重复随机数.非重复数字应落在[1,1001]范围内.但是,代码生成的数字超过1001.

directed2number := trunc(Random()*7+1);
counter := directed2number
while counter > 0
loop
to_point := trunc((random() * 1/directed2number - counter/directed2number + 1) * 1001 +1);
...
...
counter := counter - 1;
end loop;
Run Code Online (Sandbox Code Playgroud)

random postgresql stored-procedures plpgsql stored-functions

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

打印DO匿名块的执行输出

我DO在Postgres数据库中有一个匿名块,如下所示:

DO LANGUAGE plpgsql $$ 
DECLARE
     FUNC_ID smallint;
BEGIN
    SELECT COUNT(1) INTO FUNC_ID FROM FUNCTION WHERE NAME = 'addition';
    IF FUNC_ID = 0 THEN 
       INSERT INTO FUNCTION ( ID, NAME, DESCRIPTION, FUNCTION)
       values ((select (max(id)+1) from FUNCTION), 'subtraction'
              , 'calculate', 'catalog');
    END IF;

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

如果执行这段代码,它只给出输出DO.

如何将整个代码块输出到控制台?

postgresql plpgsql

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

如何使用"RAISE INFO,RAISE LOG,RAISE DEBUG"来跟踪PostgreSQL函数的登录?

CREATE OR REPLACE FUNCTION mover(src text, dst text, cpquery text, conname text, ifbin boolean) returns void as
$$
        DECLARE
                cnt integer;
                dlcnt integer;
                del_count integer;
                ret text;

        BEGIN
                SELECT  pg_catalog.dblink_copy_open(conname, dst, ifbin) INTO ret ;
                RAISE LOG 'dblink_open %',ret;

                execute 'SELECT  1 as check FROM ' || src ||' limit 1' into cnt;
                IF cnt=0 THEN
                        PERFORM pg_sleep(2);
                END IF;

                IF ifbin=true THEN
                        RAISE DEBUG 'Start to Copy data with binary';
                        execute 'COPY (' || cpquery || '  ) to …
Run Code Online (Sandbox Code Playgroud)

postgresql plpgsql debug-print

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

检查行类型时,为什么IS NOT NULL为false?

我有一个函数registration(),它应该在某些情况下向表添加一行.我已经包含了一段代码和来自通话的输出.

如果select *返回一个非空表行(它根据它执行RAISE NOTICE),我想引发异常而不添加行.该示例似乎表明它rowt不是null,但仍然rowt IS NOT NULL返回f(并且不会引发异常).

我希望这是我看不到的小事.

select * into rowt from Email where email_email = eml;
RAISE NOTICE '%, rowt IS NOT NULL:%',rowt, rowt IS NOT NULL;
if rowt IS NOT NULL THEN
   RAISE EXCEPTION 'email address, %, already registered.' , eml;
END IF;
Run Code Online (Sandbox Code Playgroud)

输出:

NOTICE:  (7,,,), rowt IS NOT NULL:f

registration 
--------------
    21
(1 row)

CREATE TABLE IF NOT EXISTS Email ( 
   email_email VARCHAR(50) NOT …
Run Code Online (Sandbox Code Playgroud)

postgresql null row plpgsql

8
推荐指数
3
解决办法
4357
查看次数

PostgreSQL在存储函数中获取并释放LOCK

我有一个需要在多个大表上执行长时间更新的函数.在更新期间,一次需要将2-3个表锁定在EXCLUSIVE模式下.

由于并非所有表都需要同时锁定,理想情况下我只想锁定那些我当时正在更新的表,然后在我完成后删除锁.

例如.

-- Lock first pair of tables
LOCK TABLE tbl1_a IN EXCLUSIVE MODE;
LOCK TABLE tbl1_b IN EXCLUSIVE MODE;

-- Perform the update on tbl1_a and tbl1_b

-- Release the locks on tbl1_a and tbl1_b
--  HOW???

-- Proceed to the next pair of tables
LOCK TABLE tbl2_a IN EXCLUSIVE MODE;
LOCK TABLE tbl2_b IN EXCLUSIVE MODE;
Run Code Online (Sandbox Code Playgroud)

不幸的是,在plpgsql中没有等效的UNLOCK语句.删除LOCK的常规方法是COMMIT事务,但这在函数内部是不可能的.

这有什么解决方案吗?在函数完成之前显式释放锁的某种方法?或者运行某种子事务(也许通过在单独的函数中运行每个更新)?

UPDATE

我接受了没有解决方案.我将每个更新写入一个单独的函数并从数据库外部进行协调.感谢大家.

sql postgresql plpgsql

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

Postgres在转换时返回函数错误/失败时的空值

我试图将text值转换为timestamp值.对于下表称为a:

 id |         c1
----+--------------------
  1 | 03-03-2000
  2 | 01-01-2000
  3 | 12/4/1990
  4 | 12 Sept 2011
  5 | 12-1-1999 12:33:12
  6 | 24-04-89 2:33 am
Run Code Online (Sandbox Code Playgroud)

我试图select用演员表演如下:

select id, c1,c1::timestampas c2 from a;

这正常工作,如果有只有前5行,但第6行地方c1是24-04-89 2:33 am它引发以下错误:

错误:日期/时间字段值超出范围:"24-04-89 2:33 am"
提示:也许您需要一个不同的"日期样式"设置.

我想要的是null那些不能被转换为时间戳而不是命令完全失败的值.像这样:

 id |         c1         |         c2
----+--------------------+---------------------
  1 | 03-03-2000         | 2000-03-03 00:00:00
  2 | 01-01-2000         | 2000-01-01 00:00:00 …
Run Code Online (Sandbox Code Playgroud)

sql postgresql casting plpgsql

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

如何在c#中返回postgresql函数的结果?控制台输出为空

我有问题,我在postgresql中有一个函数,计算两个整数,应该将结果返回到c#(npgsql)conosle,我不知道我的错误在哪里,因为调试器没有对我说什么,这是很有帮助.

所以首先是c#的代码和函数的代码.

                ...
            cmd.Parameters["x"].Value = 20;
            cmd.Parameters["y"].Value = 22;
            connection.Open();

            if (connection.State == System.Data.ConnectionState.Open) {
                //Console.WriteLine(cmd.Parameters["x"].Value);
                command.ExecuteNonQuery();
                Console.WriteLine(cmd.Parameters["sum"].Value);

            }
Run Code Online (Sandbox Code Playgroud)

现在DB的代码:

CREATE OR REPLACE FUNCTION t2(
    IN x integer,
    IN y integer,
    OUT sum integer)
  RETURNS integer AS
$BODY$BEGIN
    sum := x + y;
    INSERT INTO  t2 (x, y, sum) values (x, y, sum);
END
Run Code Online (Sandbox Code Playgroud)

所以,当我尝试运行它时,

Console.WriteLine(cmd.Parameters["sum"].Value);
Run Code Online (Sandbox Code Playgroud)

将为空且["sum"].值为NULL.我究竟做错了什么?我是对的,当我说"sum"是一个OUT变量时,我不需要返回吗?

请帮忙.

求助了,谢谢大家!@Patrick给了我正确的答案: 使用ExecuteScalar()而不是ExecuteNonQuery()

c# postgresql plpgsql

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

插入COALESCE(NULL,默认值)

我有使用UUID的表.我希望能够在有或没有UUID的情况下插入新行,因为有时客户端会生成UUID,有时则不会.

每个表都有它的核心:

CREATE TABLE IF NOT EXISTS person (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid()
);
Run Code Online (Sandbox Code Playgroud)

我正在尝试使用函数来插入行.我希望能够传递一个NULL id并获得一个默认值(生成的UUID).我有这样的事情:

CREATE OR REPLACE FUNCTION create_person(
    id UUID
) RETURNS BOOLEAN LANGUAGE plpgsql SECURITY DEFINER AS $$
BEGIN
    INSERT INTO person( id )
    VALUES (
        COALESCE(id,default)
    );
    RETURN FOUND;
END;
$$;
Run Code Online (Sandbox Code Playgroud)

我试过这个:

INSERT INTO person ( id ) VALUES (
    COALESCE(id, default),
);
Run Code Online (Sandbox Code Playgroud)

还有这个:

INSERT INTO person ( id ) VALUES (
  CASE WHEN id IS NULL THEN default ELSE id END
); …
Run Code Online (Sandbox Code Playgroud)

sql postgresql plpgsql

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

捕获所有错误psql函数异常

我正在写一个异常捕获和忽略的函数.我想抓住所有异常并忽略它.反正有没有捕获所有的例外而不是单独的?

CREATE OR REPLACE FUNCTION ADD_TABLE_TO_ARCHIVE (a TEXT, b TEXT)
RETURNS INTEGER AS $SUCCESS$
DECLARE SUCCESS INTEGER;
BEGIN
    SUCCESS = 0;
    BEGIN
        UPDATE ARCHIVE_STATUS
        SET *****
        WHERE ***;
        SUCCESS = 1;
    EXCEPTION
        WHEN UNIQUE_VIOLATION 
        SUCCESS = 0;
    END;

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

取代唯一的例外,它应该是任何例外......

exception-handling plpgsql psql

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