2016-06-22 82 views
0

我正在寫一個upsert函數爲一個表使用與更新塊,然後有條件地做插入。然後我想從整個函數中返回pks,以及是否插入或更新完成。我認爲這會工作,但我得到返回語句的歧義錯誤。我錯過了什麼?Postgres返回upsert模糊

CREATE OR REPLACE FUNCTION eai.upsert_manufacturer(
    p_user_tag_ident text 
    , p_manuf_trade_name text 
    , p_company_name text 
    , p_manuf_code bigint default null 
    , p_mf_db_site text default '0000045000000100' 
    , p_mf_db_id bigint default 1 
    , p_phys_addr text default null 
    , p_phys_city_name text default null 
    , p_phys_state_abbr text default null 
    , p_phys_postal_code text default null 
    , p_phys_country_abbr text default null 
    , p_rstat_type_code smallint default 1 
) 
RETURNS TABLE(manuf_code bigint, mf_db_site text, mf_db_id bigint, action text) 
LANGUAGE plpgsql 
AS $function$ 
declare 
begin 

    return query 
    with update_outcome as (
     update eai.manufacturer as m 
      set 
       user_tag_ident = p_user_tag_ident::text 
       , manuf_trade_name = p_manuf_trade_name::text 
       , company_name = p_company_name::text 
       , phys_addr = p_phys_addr::text 
       , phys_city_name = p_phys_city_name::text 
       , phys_state_abbr = p_phys_state_abbr::text 
       , phys_postal_code = p_phys_postal_code::text 
       , phys_country_abbr = p_phys_country_abbr::text 
       , rstat_type_code = p_rstat_type_code::smallint 
       , gmt_last_updated = now() 
     where (m.manuf_code = p_manuf_code::bigint 
      and m.mf_db_site = p_mf_db_site::text 
      and m.mf_db_id = p_mf_db_id::bigint) 
      /* Since this table is unique on user_tag_ident */ 
      or m.user_tag_ident = p_user_tag_ident 
     returning manuf_code, mf_db_site, mf_db_id, 'update'::text as action 
    ) 
    , insert_outcome as (
     insert into eai.manufacturer(
      user_tag_ident 
      , manuf_trade_name 
      , company_name 
      , manuf_code 
      , mf_db_site 
      , mf_db_id 
      , phys_addr 
      , phys_city_name 
      , phys_state_abbr 
      , phys_postal_code 
      , phys_country_abbr 
      , rstat_type_code 
      , gmt_last_updated 
     ) 
     select 
      p_user_tag_ident::text 
      , p_manuf_trade_name::text 
      , p_company_name::text 
      , coalesce(p_manuf_code::bigint, (select max(mf.manuf_code)+1 from eai.manufacturer mf where mf.mf_db_site = p_mf_db_site and mf.mf_db_id = p_mf_db_id))::bigint as manuf_code 
      , p_mf_db_site::text 
      , p_mf_db_id::int 
      , p_phys_addr::text 
      , p_phys_city_name::text 
      , p_phys_state_abbr::text 
      , p_phys_postal_code::text 
      , p_phys_country_abbr::text 
      , p_rstat_type_code::smallint 
      , now() as now 
     where not exists (select 1 from update_outcome u) 
     returning manuf_code, mf_db_site, mf_db_id, 'insert'::text as action 
    ) 
    select 
     x.manuf_code 
     , x.mf_db_site 
     , x.mf_db_id 
     , x.action 
    from (
     SELECT 
      manuf_code 
      , mf_db_site 
      , mf_db_id 
      , action 
     FROM update_outcome u 
     UNION ALL SELECT 
      manuf_code 
      , mf_db_site 
      , mf_db_id 
      , action 
     FROM insert_outcome i 
    ) x; 

end; 
$function$; 

執行:

select * from eai.upsert_manufacturer(
    p_user_tag_ident:='Sent' 
    , p_manuf_trade_name:='Sent' 
    , p_company_name:='Sent' 
    , p_phys_addr:= '672' 
    , p_phys_city_name:= 'Blargh' 
); 

和錯誤:

Kernel error: ERROR: column reference "manuf_code" is ambiguous 
LINE 19:   returning manuf_code, mf_db_site, mf_db_id, 'update'... 
         ^
DETAIL: It could refer to either a PL/pgSQL variable or a table column. 
+1

你需要一個'LOCK TABLE eai.manufacturer IN EXCLUSIVE MODE'在那裏,除非你知道你有一個函數以外的鎖。否則,這是面對併發執行時的錯誤。 –

回答

0

你必須manuf_code沒有,據我可以看到。第一個來自update_outcome,第二個來自insert部分。

+0

雖然我不能別名插入,有沒有辦法解決這個問題?所以我有點卡住了。 – KevinShaffer

+0

,但你可以別名選擇部分 – JiriS

+0

原來的問題是我的返回語句與upsert具有相同的名稱。 – KevinShaffer