3

行が存在しない場合に行を挿入し、行の ID (新規作成または既存) を返す関数を postgres で作成しようとしています。

私はこれを思いつきました:

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                                                                         
$$;                    

INSERTただし、 insideのために構文エラーが発生しますCASEINSERTこれで別の関数を作成し、この関数を で使用することで、この問題を解決できました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 に答える