Postgresql

X時如何結束功能

  • September 11, 2018

所以我的功能看起來像這樣:

create or replace function insert_stuff(a1 text, a2 text, a3 int)
returns table (id_i int, id_j int) as
$$ begin return query
with 
i1(id1) as select insert_here(a1,a2),
i2(id2) as select insert_there(a3,a2),
select id1,id2 from i1,i2;
end; $$

我需要該功能來檢查是否a1||a2 in table_1.a12在執行插入之前以及它是否在跳過該插入並移動到下一個。

我試過:

create or replace function insert_stuff(a1 text, a2 text, a3 int)
returns table (id_i int, id_j int) as
$$ begin return query
with 
i1(id1) as select insert_here(a1,a2),
i2(id2) as select insert_there(a3,a2),
select id1,id2 from i1,i2;
exception when select (select a1||a2) in (select a12 from table_1) then
end; $$

但這只會導致查詢停止

您可以簡化為:

CREATE OR REPLACE FUNCTION pg_temp.insert_stuff(_a1 text, _a2 text, _a3 int)
 RETURNS TABLE (id_i int, id_j int) AS
$func$
BEGIN 
  IF EXISTS (SELECT FROM table_1 WHERE a12 = _a1||a2) THEN  -- see below
     RETURN QUERY
     SELECT -1, NULL;
     -- RAISE EXCEPTION 'Some informative msg here'  -- alternative?
  ELSE
     RETURN QUERY
     SELECT insert_here(_a1, _a2)
          , insert_there(_a3, _a2);
  END IF;
END
$func$  LANGUAGE plpgsql;

注意更清晰(更快)IF EXISTS。看:

a12如果輸入參數或列可以為 NULL ,則任何一種變體都可能“意外”失敗!您必須定義所需的行為。

細微的區別:由於我用 simple 替換了您的 CTE 構造SELECT,因此該函式現在總是至少返回一個,即使任何嵌套函式(insert_here()insert_there()都不返回 row在這種情況下,您的版本不會返回任何內容,如果任何一個嵌套函式都不能返回任何行,這可能是一個偷偷摸摸的錯誤

我假設 Postgres 10 或更高版本(您沒有聲明)。否則,根據嵌套函式的未聲明性質,您可能需要考慮:

我發現的一種解決方案:

create or replace function insert_stuff(a1 text, a2 text, a3 int)
returns table (id_i int, id_j int) as
$$ begin 
if (select (select a1||a2) in (select a12 from table_1)) then
return query select -1;
else
return query
with 
i1(id1) as select insert_here(a1,a2),
i2(id2) as select insert_there(a3,a2),
select id1,id2 from i1,i2;
end if;
end; $$

旁注:此輸出是插入記錄,當它出錯時,它會為需要人工操作的條目提供指導,因為它們需要復雜的修訂來匹配我們在數據庫中需要的數據

引用自:https://dba.stackexchange.com/questions/217276