[英]Input table for PL/pgSQL function
我想將一個帶有表和幾列的plpgsql函數用作輸入參數。 想法是將表拆分為多個塊,並對每個部分進行處理。
我嘗試了以下功能:
CREATE OR REPLACE FUNCTION my_func(Integer)
RETURNS SETOF my_part
AS $$
DECLARE
out my_part;
BEGIN
FOR i IN 0..$1 LOOP
FOR out IN
SELECT * FROM my_func2(SELECT * FROM table1 WHERE id = i)
LOOP
RETURN NEXT out;
END LOOP;
END LOOP;
RETURN;
END;
$$
LANGUAGE plpgsql;
my_func2()
是對每個較小部分進行一些工作的函數。
CREATE or REPLACE FUNCTION my_func2(table1)
RETURNS SETOF my_part2 AS
$$
BEGIN
RETURN QUERY
SELECT * FROM table1;
END
$$
LANGUAGE plpgsql;
如果我運行:
SELECT * FROM my_func(99);
我想我應該收到為每個ID處理的前99個ID。 但它說以下行有錯誤:
SELECT * FROM my_func2(select * from table1 where id = i)
錯誤是:
子查詢只允許返回一列
為什么會這樣? 有簡單的方法可以解決此問題嗎?
這里有多種誤解 。 在嘗試高級魔術之前,請先學習基礎知識。
Postgres沒有“表變量”。 一次只能將1列或1行傳遞給一個函數。 使用臨時表或refcursor
(由@Daniel喜歡評論)通過一個完整的表。 該語法在多個地方都是無效的,因此尚不清楚這是否是您真正要嘗試的。
即使是這樣:一次處理一行或重新考慮您的方法並使用基於集合的操作(普通SQL)而不是傳遞游標可能會更好。
數據類型my_part
和my_part2
在您的問題中未定義。 可能是測試案例中的問題或問題的不足。
您似乎希望my_func2()
函數體中的表名table1
引用相同(類型!)名稱的函數參數,但是從根本上講,這至少有兩種錯誤:
您只能傳遞值 。 表名是標識符 ,而不是值。 您將需要動態構建查詢字符串,並使用plpgsql函數中的EXECUTE
執行查詢字符串。 嘗試搜索,因此她獲得了許多相關的答案。 再說一遍,那可能也不是您想要的。
table1
在CREATE or REPLACE FUNCTION my_func2(table1)
是一種類型的名稱 ,而不是參數名稱。 這意味着您的函數需要一個table1
類型的值。 顯然,您有一個同名的表,因此它應該是關聯的行類型。
my_func2()
的RETURN類型必須與您實際返回的內容匹配。 由於您要返回SELECT * FROM table1
,因此請使RETURNS SETOF table1
成為可能。
它可以只是一個簡單的SQL函數。
所有這些放在一起:
CREATE or REPLACE FUNCTION my_func2(_row table1)
RETURNS SETOF table1 AS
'SELECT ($1).*' LANGUAGE sql;
請注意括號,這對於分解行類型至關重要。 每個文檔:
此處需要括號以表明
compositecol
是列名而不是表名
但是還有更多...
不要
作為變量名,它是out
CREATE FUNCTION
語句的關鍵字。
您的主要查詢my_func()
的語法更像是偽代碼。 太多不會加起來。
演示表:
CREATE TABLE table1(table1_id serial PRIMARY KEY, txt text);
INSERT INTO table1(txt) VALUES ('a'),('b'),('c'),('d'),('e'),('f'),('g');
輔助功能:
CREATE or REPLACE FUNCTION my_func2(_row table1)
RETURNS SETOF table1 AS
'SELECT ($1).*' LANGUAGE sql;
主功能:
CREATE OR REPLACE FUNCTION my_func(int)
RETURNS SETOF table1 AS
$func$
DECLARE
rec table1;
BEGIN
FOR i IN 0..$1 LOOP
FOR rec IN
SELECT * FROM table1 WHERE table1_id = i
LOOP
RETURN QUERY
SELECT * FROM my_func2(rec);
END LOOP;
END LOOP;
END
$func$ LANGUAGE plpgsql;
呼叫:
SELECT * FROM my_func(99);
但這實際上只是概念的證明。 沒什么用。
錯誤日志告訴您..您只能在子查詢中返回一列,因此您必須將其更改為
SELECT my_func2(SELECT Specific_column_you_need FROM hasval WHERE wid = i)
一種可能的解決方案是,將funct2所需的表的主鍵傳遞給funct2,然后通過在函數內部進行SELECT *,可以獲取整個表
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.