3

我正在尝试在 postgres 中创建一个函数,如果它不存在则插入一行并返回该行的 id(新创建的或现有的)。

我想出了这个:

CREATE OR REPLACE FUNCTION                                                      
get_enttype(name character varying, module character varying)               
RETURNS integer LANGUAGE SQL STABLE AS $$                                   
    SELECT typeid FROM enttypes WHERE name = $1 AND module = $2             
$$;                                                                             

CREATE OR REPLACE FUNCTION                                                      
    ensure_enttype(name character varying, module character varying)            
    RETURNS integer LANGUAGE SQL AS $$                                          
    SELECT CASE WHEN get_enttype($1, $2) IS NULL                                
    THEN                                                                        
        INSERT INTO enttypes(name, module) VALUES ($1, $2) RETURNING typeid                                                 
    ELSE                                                                        
        get_enttype($1, $2)                                                     
    END                                                                         
$$;                    

但是,由于INSERTinside ,它会引发语法错误CASE。我设法通过创建一个单独的函数INSERT并在CASE. 它按预期工作,但这个修复似乎有点奇怪。我的问题是 - 我可以在不创建另一个函数的情况下解决这个问题吗?

4

2 回答 2

2

不,您不能在函数中使用INSERTinside 。但是,您可以:CASEsql

  • 使用带有IF ... ELSE ... END语句的 PL/PgSQL 函数;或者
  • 使用可写公用表表达式 (wCTE) 或INSERT INTO ... SELECT查询
于 2013-04-03T07:36:51.477 回答
1

纯 SQL 可以做到:

create or replace function  ensure_enttype(
    name character varying, module character varying
) returns integer language sql as $$

    insert into enttypes(name, module)
    select $1, $2
    where get_enttype($1, $2) is null
    ;
    select get_enttype($1, $2);
$$;
于 2013-04-03T16:03:25.653 回答