Postgresql

無法在 plpgsql 循環中包裝簡單的 CTE

  • March 26, 2019

對於測試數據庫,我想創建一堆測試使用者(全部使用“預設”值)。有一個表叫users,另一個叫user_properties。對於每個測試使用者,我需要在這兩個表中創建相應的條目。我已經有一個執行良好的 CTE 來執行此操作,但我無法將這個 CTE 包裝在一個循環中。

CREATE OR REPLACE FUNCTION ins() 
returns void as 
$BODY$
BEGIN
--RETURN record;

 FOR Loopid  IN 0..10 LOOP

with 
   user as (
   insert into user
   values(default) 
   returning id
   )
   ,user_property as (
   insert into user_property (property_of) 
   select id from user 
   returning id
   )
select id from user_property;

END LOOP;
END;
$BODY$
LANGUAGE 'plpgsql' VOLATILE;

它創建了函式,但在執行時會抱怨

ERROR:  query has no destination for result data
HINT:  If you want to discard the results of a SELECT, use PERFORM instead.

但似乎不可能select用 a 替換 CTE的最後一個perform- 這是一個語法錯誤。那麼我該怎麼做呢?

可以假設表結構非常簡單,因為大多數列將採用預設值。表user有一個單列iduser_properties有兩列id和- 這是表中 col的property_of外鍵。這兩列都是自動生成的序列。id``user``id

標題非常相似的幾個問題(example )的答案是 loop/cte 並不是真正必要的,所以它們對我沒有幫助。

第一:user是保留關鍵字,如果要用作表名,則需要使用雙引號:"user"但我強烈建議您找到不同的名稱。

要回答您的直接問題:只需從 CTE 中刪除最終選擇 - 這是導致錯誤的原因(因為您需要將該選擇的結果儲存在某處)。

CREATE OR REPLACE FUNCTION ins() 
returns void as 
$BODY$
declare
  loopid integer;
BEGIN
 FOR Loopid  IN 0..10 LOOP
   with new_user as (
     insert into "user"
     values(default) 
     returning id
   )
   insert into user_property (property_of) 
   select id 
   from new_user; 
 END LOOP;
END;
$BODY$
LANGUAGE plpgsql VOLATILE;

請注意,語言名稱是標識符,不應將其放在單引號中。

但是,您實際上並不需要一個函式:

with new_users as as (
 insert into "user" (id)
 select i 
 from generate_series(1,10) --<< this is the number of rows. 
 returning id
)
insert into user_property (property_of)
select id  
from new_users;

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