2017-10-28 82 views
0

我正在开发一个SQL项目。我想创建一个返回一个表的sql * Plus函数。 我已经做出这样的事情,但它不工作,我不知道为什么:在PL/SQL函数中返回表格

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”有问题

+4

咦?这看起来不像有效的pl/sql styntax /代码。 – OldProgrammer

+0

事实上,我想返回结果列表,但我发现的唯一方法是创建一个像这样的新表格 –

+1

您应该只使用一个视图。 – itsLex

回答

1

您使用我们的语法当然是Oracle PLSQL不支持的东西。在甲骨文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,使用流水线功能,它可能是如下:

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; 
/
+0

根据结果的大小,流水线功能可能是更好的选择 –

+0

@a_horse_with_no_name True。即使我们可以直接使用'sys_refcursor'。绝对不需要返回表格,但不知道OP需要什么。 – XING

+0

谢谢你,这与管道工作很好。 –