相关疑难解决方法(0)

在触发器函数中使用动态表名INSERT

我不确定如何实现以下内容:

CREATE OR REPLACE FUNCTION fnJobQueueBEFORE() RETURNS trigger AS $$
    DECLARE
        shadowname varchar := TG_TABLE_NAME || 'shadow';
    BEGIN
        INSERT INTO shadowname VALUES(OLD.*);
        RETURN OLD;
    END;
$$
LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)

即将值插入到具有动态生成名称的表中.
执行上面的代码会产生:

ERROR:  relation "shadowname" does not exist
LINE 1: INSERT INTO shadowname VALUES(OLD.*)
Run Code Online (Sandbox Code Playgroud)

它似乎表明变量不会作为表名扩展/允许.我在Postgres手册中没有发现这个.

我已经尝试过EXECUTE这样的事情:

  EXECUTE 'INSERT INTO ' || quote_ident(shadowname) || ' VALUES ' || OLD.*;
Run Code Online (Sandbox Code Playgroud)

但没有运气:

ERROR:  syntax error at or near ","
LINE 1: INSERT INTO personenshadow VALUES (1,sven,,,)
Run Code Online (Sandbox Code Playgroud)

RECORD类型似乎失去了:OLD.*似乎被转换为字符串,并得到的重新解析,导致各种各样的类型的问题(例如NULL值). …

postgresql triggers dynamic-sql plpgsql

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

PL/pgSQL函数中的可选参数

我正在尝试用可选参数编​​写PL/pgSQL函数.它基于过滤的记录集(如果指定)执行查询,否则对表中的整个数据集执行查询.

例如(PSEUDO CODE):

CREATE OR REPLACE FUNCTION foofunc(param1 integer, param2 date, param2 date, optional_list_of_ids=[]) RETURNS SETOF RECORD AS $$
    IF len(optional_list_of_ids) > 0 THEN
        RETURN QUERY (SELECT * from foobar where f1=param1 AND f2=param2 AND id in optional_list_of_ids);
    ELSE
        RETURN QUERY (SELECT * from foobar where f1=param1 AND f2=param2);
    ENDIF
$$ LANGUAGE SQL;
Run Code Online (Sandbox Code Playgroud)

实现此功能的正确方法是什么?

顺便说一句,我想知道如何在另一个外部函数中调用这样的函数.我就是这样做的 - 它是正确的,还是有更好的方法?

CREATE FUNCTION foofuncwrapper(param1 integer, param2 date, param2 date) RETURNS SETOF RECORD AS $$
BEGIN
   CREATE TABLE ids AS SELECT id from …
Run Code Online (Sandbox Code Playgroud)

postgresql parameters stored-procedures plpgsql parameter-passing

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

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万
查看次数

EXECUTE格式()中整数变量的格式说明符?

CREATE OR REPLACE FUNCTION getParentLtree(parent_id bigint, tbl_name varchar) 
  RETURNS ltree AS
$BODY$
DECLARE
   parent_ltree ltree;
BEGIN
-- This works fine:
-- select into parent_ltree l_tree from tbl1 where id = parent_id;

EXECUTE format('select into parent_ltree l_tree from %I
                where id = %I', tbl_name,parent_id);

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

上述功能有2个问题:

  1. parent_idinteger,但它会被替换引号?int变量的正确格式说明符是什么?
  2. select into不起作用EXECUTE?如何使上面的注释查询使用表名传递?

postgresql string-concatenation dynamic-sql plpgsql

6
推荐指数
2
解决办法
7021
查看次数

错误:具有默认值的输入参数也必须具有默认值

我试图将默认值设置为参数列表中的函数内的变量,但收到错误:

 Create or replace function test(name varchar default null
                               , city varchar default null
                               , phonenumber varchar(20) default null
                               , out sno bigint, address varchar)
   returns void as
 $$
 Declare 
        phonenumber AS VarChar(20);
 Begin
        phonenumber : =phonenumber; 

    SELECT sno = MAX(ssno)+1 FROM emp;

    IF(sno IS NULL)  then
           sno=IDENT_CURRENT('emp')+1;
    end;

    raise info '%',name;
    raise info '%',city;
    raise info '%',phonenumber;
    raise info '%',address;

    insert into emp(ename,ecity,ephonenumber,eaddress)
    values(name,city,phonenumber,address);

 end;
 $$
 langauge plpgsql;
Run Code Online (Sandbox Code Playgroud)

例:

 Create or replace function test(name varchar default null
                               , city …
Run Code Online (Sandbox Code Playgroud)

postgresql plpgsql default-value

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