标签: plpgsql

创建一个名称由变量传递的模式

我想创建一个带有由变量传递的名称的模式.例:

CREATE OR REPLACE FUNCTION test1("name" character varying)
  RETURNS void AS
'CREATE SCHEMA "name";'
  LANGUAGE 'sql' VOLATILE
  COST 100;
Run Code Online (Sandbox Code Playgroud)

postgresql plpgsql

9
推荐指数
1
解决办法
1752
查看次数

PostgreSQL:正则表达式转义函数

为了放弃阅读整个问题,我的基本问题是:
PostgreSQL中是否有一个函数来转义字符串中的正则表达式字符?

我已经探测过文档,但无法找到这样的功能.

这是完整的问题:

在PostgreSQL数据库中,我有一个包含唯一名称的列.我还有一个定期在此字段中插入名称的进程,并且为了防止重复,如果需要输入已存在的名称,它会在末尾附加一个空格和括号.

即姓名,姓名(1),姓名(2),姓名(3)等

就目前而言,我使用以下代码来查找要在系列中添加的下一个数字(用plpgsql编写):

var_name_id := 1;

SELECT CAST(substring(a.name from E'\\((\\d+)\\)$') AS int)
INTO var_last_name_id
FROM my_table.names a
WHERE a.name LIKE var_name || ' (%)'
ORDER BY CAST(substring(a.name from E'\\((\\d+)\\)$') AS int) DESC
LIMIT 1;

IF var_last_name_id IS NOT NULL THEN
    var_name_id = var_last_name_id + 1;
END IF;

var_new_name := var_name || ' (' || var_name_id || ')';
Run Code Online (Sandbox Code Playgroud)

(var_name包含我试图插入的名称.)

这暂时有效,但问题出在WHERE声明中:

WHERE a.name LIKE var_name || ' (%)'
Run Code Online (Sandbox Code Playgroud)

此检查不会验证有%问题的数字,并且它不会考虑多个括号,如"Name((1))",如果存在任何一种情况,则会抛出强制转换异常.

该WHERE声明确实需要像更多的东西: …

regex postgresql escaping plpgsql pattern-matching

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

PHP数组到postgres数组

现在php无法直接用postgresql数组工作.例如,php采用postgresql数组,如'{"foo","bar"}'

我需要简单的PHP函数来从php数组创建多维postgresql数组.

我认为实验性的pg_convert()不是最优的,因为它需要额外的数据来形成数据库输出的简单数组字符串,也许我误解了这个函数的想法.

例如,我需要转换

$from=array(  array( "par_1_1","par_1_2" ), array( "array_2_1", "array_2_2" )  );
$to='{{"par_1_1","par_1_2"},{"par_2_1","par_2_2"}}';
Run Code Online (Sandbox Code Playgroud)

我可以使用array_walk_recursive()来转换数组中最深的元素吗?

php arrays postgresql plpgsql

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

带有RETURNS TABLE(id整数)的PostgreSQL存储过程返回所有NULL

我在PostgreSQL 8.4中有一个存储过程,它根据作为参数传入的整数值调用另一个存储过程.调用那些存储过程,使它们返回一个整数列的关系.我遇到的问题是外部存储过程总是返回具有正确行数但具有所有id的NULL的关系.

这是存储过程简化为最简单的形式:

CREATE OR REPLACE FUNCTION spa(count integer) 
RETURNS TABLE (id integer) AS $$
BEGIN
    RETURN QUERY SELECT generate_series(1, count);
END;
$$ LANGUAGE plpgsql;

CREATE OR REPLACE FUNCTION spb(count integer) 
RETURNS TABLE (id integer) AS $$
BEGIN
    RETURN QUERY SELECT generate_series(1, count);
END;
$$ LANGUAGE plpgsql;

CREATE OR REPLACE FUNCTION conditional_relation_return(objectType integer, count integer) 
RETURNS TABLE (id integer) AS $$
BEGIN
    IF objectType = 1 THEN
        RETURN QUERY SELECT id FROM spa(count);
    ELSIF objectType = 2 OR objectType = …
Run Code Online (Sandbox Code Playgroud)

sql postgresql plpgsql

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

PostgreSQL - 在存储过程中编写动态sql,返回结果集

如何编写包含动态生成的SQL语句的存储过程,该语句返回结果集?这是我的示例代码:

CREATE OR REPLACE FUNCTION reporting.report_get_countries_new (
  starts_with varchar,
  ends_with varchar
)
RETURNS TABLE (
  country_id integer,
  country_name varchar
) AS
$body$
DECLARE
  starts_with ALIAS FOR $1;
  ends_with ALIAS FOR $2;
  sql VARCHAR;
BEGIN

    sql = 'SELECT * FROM lookups.countries WHERE lookups.countries.country_name >= ' || starts_with ;

    IF ends_with IS NOT NULL THEN
        sql = sql || ' AND lookups.countries.country_name <= ' || ends_with ;
    END IF;

    RETURN QUERY EXECUTE sql;

END;
$body$
LANGUAGE 'plpgsql'
VOLATILE
CALLED ON NULL INPUT …
Run Code Online (Sandbox Code Playgroud)

postgresql resultset execute dynamic-sql plpgsql

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

当列不存在时,Postgres返回默认值

我有一个查询,如果缺少某个列,我基本上需要一个回退值.我想知道我是否可以在我的查询中完全处理这个问题(而不是先探测并发送一个单独的查询.本质上我正在寻找一个等效的COALESCE处理丢失列的情况.

想象一下以下2个表.

T1
id | title | extra
1    A     | value

- and -

T2
id | title
1    A
Run Code Online (Sandbox Code Playgroud)

我希望能够使用相同的查询从这些表中的任何一个中进行选择.

例如,如果t2实际上有一个我可以使用的"额外"列

 SELECT id,title, COALESCE(extra, 'default') as extra
Run Code Online (Sandbox Code Playgroud)

但是只有在列值为NULL时才有效,而不是在列完全丢失时.

我更喜欢SQL版本,但我也可以接受PLPGSQL函数(行为类似于COALLESCE).

SQL纯粹主义者的注意事项:我真的不想辩论为什么我想在SQL中而不是在应用程序逻辑中这样做(或者为什么我不会只是将列永久地添加到模式中)所以请限制你的评论/答案具体要求,而不是你对数据库"正确性"的看法,或者其他任何可能会冒犯你的问题.

sql postgresql plpgsql

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

为什么我在批处理从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
查看次数

检查行类型时,为什么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
查看次数

捕获所有错误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
查看次数