簡體   English   中英

PL / pgSQL函數的輸入表

[英]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_partmy_part2在您的問題中未定義。 可能是測試案例中的問題或問題的不足。

  • 您似乎希望my_func2()函數體中的表名table1引用相同(類型!)名稱的函數參數,但是從根本上講,這至少有兩種錯誤:

    1. 您只能傳遞 表名是標識符 ,而不是值。 您將需要動態構建查詢字符串,並使用plpgsql函數中的EXECUTE執行查詢字符串。 嘗試搜索,因此她獲得了許多相關的答案。 再說一遍,那可能也不是您想要的。

    2. table1CREATE 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);

SQL提琴。

但這實際上只是概念的證明。 沒什么用。

錯誤日志告訴您..您只能在子查詢中返回一列,因此您必須將其更改為

SELECT my_func2(SELECT Specific_column_you_need FROM hasval WHERE wid = i)

一種可能的解決方案是,將funct2所需的表的主鍵傳遞給funct2,然后通過在函數內部進行SELECT *,可以獲取整個表

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM