PostgreSQL:如何让我的函数 return 获得我插入的新行的 ID?

PostgreSQL: How do I have my function return the id of the new row I inserted?

我是 sql

的新手

这是我的错误

SQL Error [42601]: ERROR: syntax error at or near "("

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;

我建议:

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;如果员工不存在,则不插入任何内容,函数 returns null

这里有一个 demo on DB Fiddle 演示了函数的工作原理。

您的代码中存在多个错误。首先 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;