【问题标题】:PostgreSQL: How do I have my function return the id of the new row I inserted?PostgreSQL:如何让我的函数返回我插入的新行的 id?
【发布时间】:2020-12-25 23:15:59
【问题描述】:

我是 sql 新手

这是我的错误

SQL 错误 [42601]:错误:“(”或附近的语法错误

CREATE OR REPLACE FUNCTION func_add_reimbursement_ticket( f_employee text, f_amount decimal, f_request_type text, f_description text )
    RETURNS int as 
$id_num$
  DECLARE 
      id_num int = null; 
  BEGIN 
      SELECT username FROM employee WHERE username = f_employee; 
      IF NOT FOUND THEN 
          id_num := -1; 
      else 
          SET id_num TO (INSERT INTO reimbursement_ticket (employee, amount, request_type, description)
       VALUES (f_employee, f_amount, f_request_type, f_description) RETURNING id); 
      END IF; 
  RETURN (id_num); 
END;
$id_num$ 
LANGAUGE plpgsql;

【问题讨论】:

    标签: sql postgresql sql-insert sql-function


    【解决方案1】:

    您的代码中有多个错误。首先LANGAUGE 必须是LANGUAGE。

    变量are assigned 使用:=,而不是set。

    但是如果要将查询的结果存储到变量中,则需要使用INTO 子句。

    SELECT 的结果必须存储在某个地方。如果你不想这样,你需要使用perform。或者,您可以使用if not exists

    综上所述,函数应该如下所示:

    CREATE OR REPLACE FUNCTION func_add_reimbursement_ticket( f_employee text, f_amount decimal, f_request_type text, f_description text )
        RETURNS int 
    as 
    $id_num$
    DECLARE 
      id_num int; 
    BEGIN 
      if not exists (select * FROM employee WHERE username = f_employee) then
        return -1;
      end if;
    
      INSERT INTO reimbursement_ticket (employee, amount, request_type, description)
      VALUES (f_employee, f_amount, f_request_type, f_description) 
      RETURNING id into id_num;
    
      RETURN id_num; 
    END;
    $id_num$ 
    LANGUAGE plpgsql;
    

    【讨论】:

    • 谢谢!很有意义。我也很感谢你的解释。
    • @JeffEnriquez 如果该答案解决了您的问题,那么请accept 它,以便您的问题被标记为已解决。
    【解决方案2】:

    我建议:

    create or replace function func_add_reimbursement_ticket( 
        f_employee     text, 
        f_amount       decimal, 
        f_request_type text, 
        f_description  text
    )
    returns int as $id_num$
    declare
        id_num int = null;
    begin
        
        insert into reimbursement_ticket (employee, amount, request_type, description)
        select *
        from (values (f_employee, f_amount, f_request_type, f_description)) 
            as v(employee, amount, request_type, description)
        where exists (select 1 from employee where username = v.employee)
        returning id into id_num;
      
        return id_num;
        
    end; 
    $id_num$ language plpgsql;
    

    理由:

    • 这修复了语法故障,尤其是在变量赋值上

    • 一种优化是将员工的存在检查直接移动到insert查询,使用exists;如果员工不存在,则不插入任何内容,函数返回null

    这是一个 demo on DB Fiddle,它演示了函数的工作原理。

    【讨论】:

    • 谢谢!我将不得不对此进行更多研究。这有点令人困惑。我熟悉 oop 语言,但不熟悉 sql。不过肯定想学。感谢您的帮助:)
    猜你喜欢
    • 2011-09-27
    • 1970-01-01
    • 2016-11-27
    • 1970-01-01
    • 1970-01-01
    • 2020-07-18
    • 1970-01-01
    • 1970-01-01
    • 2019-07-05
    相关资源
    最近更新 更多