【问题标题】:Return a table in a PL/SQL function在 PL/SQL 函数中返回表
【发布时间】:2018-04-10 03:39:19
【问题描述】:

我正在处理一个 SQL 项目。我想创建一个返回表的 sql*Plus 函数。 我做了这样的东西,但它不起作用,我不知道为什么:

CREATE OR REPLACE FUNCTION changeNbPersonnes(recette IN int, nbPersonne IN int)
RETURN table_res TABLE
(
  idIngredient int NOT NULL,
  nomIngredient varchar(255) NOT NULL,
  quantite int NOT NULL
)
AS
  CURSOR curseur_etape IS
  SELECT * FROM IngredientRecette ir
  JOIN recette r
  ON ir.idrecette=r.idrecette
  JOIN ingredient i
  ON ir.idingredient=i.idingredient
  WHERE r.idrecette=recette;
BEGIN
  FOR row_ingredient IS
    INSERT INTO res(idIngredient,nomIngredient,quantite)
    VALUES(
      row_ingredient.idingredient,
      row_ingredient.Nom,
      row_ingredient.quantite
    );
  END FOR;
  RETURN res;
END;
/

你能帮帮我吗? “RETURN table_res TABLE”有问题

【问题讨论】:

  • 嗯?这看起来不像有效的 pl/sql 语法/代码。
  • 事实上我想返回一个结果列表,但我发现的唯一方法是创建一个这样的新表
  • 你应该只使用视图。
  • 您能否提供表 r 和 ir 的(相关)列的列表(和类型)?请解释如何处理输入参数 nbPersonne?

标签: sql oracle plsql


【解决方案1】:

您使用的语法肯定是 Oracle PLSQL 不支持的。在 oracle PLSQL 中,您需要执行以下操作:

-- Create Object of your table
CREATE TYPE TABLE_RES_OBJ AS OBJECT (
     IDINGREDIENT                  INT ,
     NOMINGREDIENT                 VARCHAR (255) ,
     QUANTITE                      INT 
);

--Create a type of your object 
CREATE TYPE TABLE_RES AS TABLE OF TABLE_RES_OBJ;
/

--Function Use the type created as Return Type
CREATE OR REPLACE FUNCTION CHANGENBPERSONNES (
     RECETTE      IN   INT,
     NBPERSONNE   IN   INT)
     RETURN TABLE_RES
AS
     CURSOR CURSEUR_ETAPE
     IS
          SELECT  TABLE_RES_OBJ (IR.*)
            FROM INGREDIENTRECETTE IR 
            JOIN RECETTE R ON IR.IDRECETTE =R.IDRECETTE
                 JOIN INGREDIENT I ON IR.IDINGREDIENT = I.IDINGREDIENT
           WHERE R.IDRECETTE = RECETTE;

     VAR       TABLE_RES:= TABLE_RES();
BEGIN
     OPEN CURSEUR_ETAPE;

     LOOP
          FETCH CURSEUR_ETAPE
          BULK COLLECT INTO VAR LIMIT 100;

          EXIT WHEN CURSEUR_ETAPE%NOTFOUND;
     END LOOP;

     CLOSE CURSEUR_ETAPE;

     RETURN VAR;
END;
/

或者按照@a_horse_with_no_name,使用PipeLine函数,可能如下:

CREATE OR REPLACE FUNCTION CHANGENBPERSONNES (RECETTE      IN INT,
                                              NBPERSONNE   IN INT)
   RETURN TABLE_RES
   PIPELINED
AS
   CURSOR CURSEUR_ETAPE
   IS
      SELECT *
        FROM INGREDIENTRECETTE IR
             JOIN RECETTE R ON IR.IDRECETTE = R.IDRECETTE
             JOIN INGREDIENT I ON IR.IDINGREDIENT = I.IDINGREDIENT
       WHERE R.IDRECETTE = RECETTE;
BEGIN
   FOR i IN CURSEUR_ETAPE
   LOOP
      PIPE ROW (TABLE_RES_OBJ (i.idingredient, i.Nom, i.quantite));
      EXIT WHEN CURSEUR_ETAPE%NOTFOUND;
   END LOOP;

   RETURN;
END;
/

【讨论】:

  • 根据结果的大小,流水线函数可能是更好的选择
  • @a_horse_with_no_name 是的。甚至我们可以直接使用sys_refcursor。绝对不需要返回表但不知道OP需要什么。
猜你喜欢
  • 1970-01-01
  • 2021-08-30
  • 2013-05-06
  • 2013-02-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-31
相关资源
最近更新 更多