相关疑难解决方法(0)

PostgreSQL函数是事务性的吗?

PostgreSQL函数如下面的自动事务是什么?

CREATE OR REPLACE FUNCTION refresh_materialized_view(name)
  RETURNS integer AS
$BODY$
 DECLARE
     _table_name ALIAS FOR $1;
     _entry materialized_views%ROWTYPE;
     _result INT;
 BEGIN          

     EXECUTE 'TRUNCATE TABLE ' || _table_name;

     UPDATE materialized_views
     SET    last_refresh = CURRENT_TIMESTAMP
     WHERE  table_name = _table_name;

     RETURN 1;
END
$BODY$
  LANGUAGE plpgsql VOLATILE SECURITY DEFINER;
Run Code Online (Sandbox Code Playgroud)


换句话说,如果在执行函数期间发生错误,是否会回滚任何更改?如果这不是默认行为,我该如何使该函数成为事务性的

postgresql transactions

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

我可以让plpgsql函数返回一个整数而不使用变量吗?

像这样的东西:

CREATE OR REPLACE FUNCTION get(param_id integer)
  RETURNS integer AS
$BODY$
BEGIN
SELECT col1 FROM TABLE WHERE id = param_id;
END;
$BODY$
  LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)

我想避免DECLARE这样做.

postgresql variables parameters function plpgsql

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

PostgreSQL:Query没有结果数据的目的地

我试图通过使用dblink through函数从远程数据库获取数据,但收到错误"查询没有结果数据的目标".我使用plpgsql语言做同样的事情.

功能:

CREATE OR REPLACE FUNCTION fun()
  RETURNS text AS
$$
begin
select dblink_connect(
      'port=5432 dbname=test user=postgres password=****');

WITH a AS (
SELECT *
FROM dblink(
    'SELECT slno,fname,mname,lname
    FROM    remote_tbl'
     ) AS t (slno int, fname text, mname text, lname text)
)
, b AS (
INSERT INTO temptab1
SELECT slno, name
FROM   a
)
, c AS (
INSERT INTO temptab2
SELECT slno, name
FROM   a
)
INSERT INTO temptab3
SELECT slno, name
FROM   a;


select dblink_disconnect(); …
Run Code Online (Sandbox Code Playgroud)

postgresql dblink common-table-expression

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

PostgreSQL参数化表函数中的Order By/Limit

我有一个sql函数,它执行一个简单的sql select语句:

CREATE OR REPLACE FUNCTION getStuff(param character varying)
  RETURNS SETOF stuff AS
$BODY$
    select *
    from stuff
    where col = $1
$BODY$
  LANGUAGE sql;
Run Code Online (Sandbox Code Playgroud)

现在我调用这个函数是这样的:

select * from getStuff('hello');
Run Code Online (Sandbox Code Playgroud)

如果我需要订购并限制结果order bylimit条款,我有哪些选择?

我想这样的查询:

select * from getStuff('hello') order by col2 limit 100;
Run Code Online (Sandbox Code Playgroud)

效率不高,因为表中的所有行都stuff将由函数返回,getStuff然后按限制排序和切片.

但即使我是对的,如何通过sql语言函数的参数传递顺序也没有简单的方法.只能传递值,而不能传递sql语句的一部分.

另一种选择是用plpgsql语言创建函数,在那里可以构造查询并通过它来执行EXECUTE.但这也不是一个非常好的方法.

那么,有没有其他方法可以实现这一目标?或者你会选择什么选择?在函数外部订购/限制,还是plpgsql?

我正在使用postgresql 9.1.

编辑

我修改了CREATE FUNCTION语句,如下所示:

CREATE OR REPLACE FUNCTION getStuff(param character varying, orderby character varying)
  RETURNS SETOF stuff AS
$BODY$
    select t.* …
Run Code Online (Sandbox Code Playgroud)

sql database postgresql dynamic-sql plpgsql

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

从PostgreSQL函数返回SETOF行

我有一种情况,我想在两个视图之间返回连接.那是很多专栏.在sql server中很容易.但是在PostgreSQL中我加入时.我收到错误"需要列定义列表".

有什么方法可以绕过这个,我不想提供返回列的定义.

CREATE OR REPLACE FUNCTION functionA(username character varying DEFAULT ''::character varying, databaseobject character varying DEFAULT ''::character varying)
  RETURNS SETOF ???? AS
$BODY$
Declare 
SqlString varchar(4000) = '';
BEGIN
IF(UserName = '*') THEN
   Begin
   SqlString  := 'select * from view1 left join ' + databaseobject  + ' as view2 on view1.id = view2.id';
   End;
ELSE
    Begin
    SqlString := 'select * from view3 left join ' + databaseobject  + ' as view2 on view3.id = view2.id';
    End;
END IF; 
execute …
Run Code Online (Sandbox Code Playgroud)

postgresql dynamic-sql plpgsql postgresql-9.2

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

一起执行多个功能而不会降低性能

我有这个过程,必须使用pl/pgsql进行一系列查询:

--process:
SELECT function1();
SELECT function2();
SELECT function3();
SELECT function4();
Run Code Online (Sandbox Code Playgroud)

为了能够在一次调用中执行所有操作,我创建了一个过程函数:

CREATE OR REPLACE FUNCTION process()
  RETURNS text AS
$BODY$
BEGIN
    PERFORM function1();
    PERFORM function2();
    PERFORM function3();
    PERFORM function4();
    RETURN 'process ended';
END;
$BODY$
  LANGUAGE plpgsql
Run Code Online (Sandbox Code Playgroud)

问题是,当我总结每个函数自身所用的时间时,总计为200秒,而函数所process()用的时间超过一个小时!

也许这是一个内存问题,但我不知道postgresql.conf应该改变哪种配置.

DB在Debian 8中的PostgreSQL 9.4上运行.

postgresql plpgsql database-performance query-performance postgresql-performance

10
推荐指数
1
解决办法
6934
查看次数

什么是VARIADIC声明在postgreSQL中意味着什么?

在PostgreSQL 9.3.4发行说明中它说:

Ensure that the planner sees equivalent VARIADIC and non-VARIADIC function calls as equivalent (Tom Lane)
Run Code Online (Sandbox Code Playgroud)

我搜索了PostgreSQL手册,找不到它的定义.

我发现它与功能参数模式(IN,OUT,VARIADIC)有关,但我不明白这意味着什么?我什么时候想用它?如果函数具有VARIADIC属性,它在性能方面意味着什么?

sql postgresql

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

根据它们的用途,预准备语句和SQL或PL/pgSQL函数之间有什么区别?

在PostgreSQL中,就其目的,优点和缺点而言,预准备语句与SQL或PL/pgSQL函数之间有什么区别?我们什么时候用哪个?

在这个非常简单的例子中,它们是否正常工作,对吗?

CREATE TABLE foo (id INT, name VARCHAR(80)); 

CREATE FUNCTION myfunc1(INT, VARCHAR(80)) RETURNS void AS ' 
INSERT INTO foo VALUES ($1, $2);
' LANGUAGE SQL; 

SELECT myfunc1(3, 'ben');

CREATE FUNCTION myfunc2(INT, VARCHAR(80)) RETURNS void AS ' 
BEGIN
INSERT INTO foo VALUES ($1, $2);
END' LANGUAGE plpgsql; 

SELECT myfunc2(3, 'ben');

PREPARE fooplan (INT, VARCHAR(80)) AS
    INSERT INTO foo VALUES($1, $2);
PREPARE

EXECUTE fooplan(3, 'ben');
Run Code Online (Sandbox Code Playgroud)

postgresql plpgsql prepared-statement sql-function

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

是否存在可以在组内返回第一个非空值的聚合函数?

我正在使用Oracle XE 10g.

请你仔细阅读我的问题.我有一个奇怪的用例,但请耐心等待.

假设我有以下记录:

Table person
Name  YearOfBirth
a     null
a     2001
a     2002
b     1990
b     null
c     null
c     2001
c     2009
Run Code Online (Sandbox Code Playgroud)

基本上如果我执行以下查询:

select
  p.Name, max(p.YearOfBirth)
from
  person p
group by
  p.Name
Run Code Online (Sandbox Code Playgroud)

这将为我提供具有不同名称的记录,并且每个不同的名称将与其组内的YearOfBirth的最大值配对.在给定的示例中,Name ='a'的组,最大YearOfBirth是2002.

如果max()是一个返回给定组中列的最大值的聚合函数,是否有一个函数返回该组中非空的第一个值而不是给我最大值,我想要你能找到的第一个值,只要它不是null.

请不要问我为什么我不能简单地使用min()或max()代替.

显然我不能在这里使用rownum,因为这样做会限制我可以获得的组数.

sql database oracle plsql oracle10g

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

如何在不创建函数的情况下运行plpgsql?

我想在Postgres中以编程方式运行SQL,而无需创建函数。

原因:确保我的plpgsql可以事先工作,并且在将查询提交给函数之前先对其进行“解释分析”。

我是Postgres的新手,我认为这很简单。我找不到任何示例。也许不可能吗?下面的代码如何工作?

DO
$body$
DECLARE
  v_name_short VARCHAR;
BEGIN

v_name_short := 'test Account 1';

     RETURN QUERY
        SELECT 
            a.name_short, 
            a.name_long
        FROM enterprise.account a 
        WHERE 
            CASE WHEN v_name_short IS NOT NULL THEN
               LOWER(a.name_short) = LOWER(v_name_short)
            ELSE
               1 = 1   
            END;
END;
$body$
LANGUAGE 'plpgsql';
Run Code Online (Sandbox Code Playgroud)

同样,这里的目标是测试我的SQL,就像在这种情况下,我想确保我的CASE语句仍在使用我创建的索引(LOWER(name_short))。无论如何,我收到此错误消息:

错误:无法在非SETOF函数中使用RETURN QUERY

我要问的在Postgres中可能吗?如果没有,是否可以查询函数内部的分析计划?

postgresql plpgsql

5
推荐指数
3
解决办法
6124
查看次数