IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

PL/SQL Oracle Discussion :

Renvoyer une table avec une proc. stock.


Sujet :

PL/SQL Oracle

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    79
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 79
    Points : 68
    Points
    68
    Par défaut Renvoyer une table avec une proc. stock.
    Bonjour à tous,

    J'ai une questionqui certainement vous semblera à tous très facile !!

    J'ai créé une procédure qui fait des INSERT et des UPDATE dans une table. Jusque là tout va bien.
    Là où ça pose problème c'est que je souhaite récupérer en sortie la table en question.
    Voilà ce que je voudrais faire :

    Declare
    -- variables et curseurs
    Begin
    --Insert et Update dans MA_TABLE
    /*partie qui ne fonctionne pas */
    select * from MA_TABLE;
    end;

    Je suis sous Orable 9i et pour répondre à la question qui brule vos levres : je suis obligée de passer parce biais car j'utilise derrière un outil de décisionnel qui demande que les procédures renvoient des valeurs pour fonctionner.

    Merci par avance pour votre aide et n'hésitez pas à poser des questions si je n'est pas été claire !!

    @+

  2. #2
    Nouveau membre du Club
    Homme Profil pro
    Inscrit en
    Septembre 2007
    Messages
    37
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 37
    Points : 29
    Points
    29
    Par défaut
    Si j'ai bien compris ce que tu veux, il te faut utiliser une fonction et renvoyer un curseur sur ta table.
    1)il te faut créer un type (dans ton package, si tu en as un ou dans un nouveau) pour la référence de curseurqu’on va renvoyer
    create or replace package Types AS
    type curseur_type is ref cursor;
    end Types;


    2) ta fonction ressemblerait à :

    create or replace
    function maFonction()
    return Types.curseur_type
    is
    monCurseur Types.curseur_type;
    begin
    open monCurseur for
    select * from MA_TABLE;
    return monCurseur;
    end;

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    79
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 79
    Points : 68
    Points
    68
    Par défaut
    Merci pour l'info, je teste de ce pas !!!

    Juste une précision : peut-on appeler une fonction dans une procédure ?

    Pourquoi ? Parce que forcément mon outil décisionnel n'accepte que les procédures stockées et pas autres choses

    @+
    Darcynette

  4. #4
    Nouveau membre du Club
    Homme Profil pro
    Inscrit en
    Septembre 2007
    Messages
    37
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 37
    Points : 29
    Points
    29
    Par défaut
    Citation Envoyé par Darcynette Voir le message
    Juste une précision : peut-on appeler une fonction dans une procédure ?
    Tu peux.
    Ou alors, tu gardes ta procédure et tu lui mets le curseur en paramètre out

    procedure maProc(monCurseur out Types.curseur_type)

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    79
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 79
    Points : 68
    Points
    68
    Par défaut
    euh...
    Je comprends pas comment utiliser la fonction dans ma procédure...
    d'après les docs, il faut affecter la fonction à une variable !
    Je pensais utiliser un curseur mais du coup, je ne vois pas comment afficher le résultat de ma fonction

    Si quelqu'un peut encore m'aider

    Merci
    Darcynette

  6. #6
    Futur Membre du Club
    Inscrit en
    Février 2003
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Février 2003
    Messages : 7
    Points : 8
    Points
    8
    Par défaut
    essaye ceci

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
     
    procedure maProc ( C1 OUT SYS_REFCURSOR)
    IS
    BEGIN
    open C1 for select taFonction from dual;
    END;

  7. #7
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    79
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 79
    Points : 68
    Points
    68
    Par défaut
    Ca marche !!!

    Merci pour votre aide, j'ai une épine dans le pied en moins !!

    @+
    Darcynette

  8. #8
    jcd
    jcd est déconnecté
    Membre à l'essai
    Profil pro
    Inscrit en
    Février 2003
    Messages
    29
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2003
    Messages : 29
    Points : 19
    Points
    19
    Par défaut
    Bonjour,

    Curieux de creuser également ce problème j'ai créé (comme expliqué sauf erreur de ma part...) un type, une fonction et une procédure :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    CREATE OR REPLACE PACKAGE TYPES AS
    	-- Nouveau type de données de type "curseur"
    	TYPE CURSEUR_TYPE IS REF CURSOR;
    END TYPES;
     
     
    CREATE OR REPLACE FUNCTION f_lit_table RETURN types.curseur_type IS moncurseur types.curseur_type;
    BEGIN
    	-- Lecture de la table dans le curseur
      OPEN moncurseur FOR
      SELECT DISTINCT first_name,
        last_name
      FROM employees
      ORDER BY last_name,
        first_name;
      RETURN moncurseur;
    END;
     
     
    CREATE OR REPLACE PROCEDURE sp_lit_table(parCurseur OUT sys_refcursor) AS
    BEGIN
      -- Lecture du curseur
      OPEN parCurseur FOR
      SELECT f_lit_table()
      FROM dual;
    END sp_lit_table;
    Si je fais un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT F_Liste_table() FROM DUAL;
    je n'obtiens qu'une ligne d'un champ qui contient les données imbriquées ("nested")... pourquoi n'obtiendrais-je pas toutes les lignes (avec tous les champs) ?? Et comment le faire ?

    ensuite, si je fais un j'obtiens une erreur "ORA06-553 : numéro ou type d'arguments erronés dans appel sp_lit_table()...

    Et, dernière chose pour ma gouverne personnelle, dans une procédure stockée MySQL (je ne recherche pas la polémique dans cette salle Oracle ), en plus des paramètres IN et OUT je peux faire des
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT x, y, z FROM toto;
    pour retourner tout simplement un résultat. Quelle justification pouvez vous me donner pour Oracle de ne pas le permettre (aussi simplement) ?

    D'avance, merci

  9. #9
    jcd
    jcd est déconnecté
    Membre à l'essai
    Profil pro
    Inscrit en
    Février 2003
    Messages
    29
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2003
    Messages : 29
    Points : 19
    Points
    19
    Par défaut
    Voici ma réponse à ma question :

    Tout d'abord, en préambule, je crée un type personnalisé : un curseur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    CREATE OR REPLACE PACKAGE TYPES AS
    	-- Nouveau type de données de type "curseur"
    	TYPE CURSEUR_TYPE IS REF CURSOR;
    END TYPES;
    Ensuite différents cas de figure :
    • 1ère possibilité : créer une fonction qui retourne le résultset
    • 2ème possibilité : créer une procédure qui retourne le resultset
    • 3ème possibilité : créer en plus de la 1ère fonction qui retourne le resultset une procédure qui englobe cette fonction




    1ère possibilité (fct simple) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    -- -----------------------------------------------------------------------
    -- Fonction qui retourne un curseur
    -- -----------------------------------------------------------------------
    CREATE OR REPLACE FUNCTION F_LIT_TABLE RETURN TYPES.CURSEUR_TYPE IS MONCURSEUR TYPES.CURSEUR_TYPE;
    BEGIN
    	-- Lecture de la table dans le curseur
    	OPEN MONCURSEUR FOR
    	  SELECT DISTINCT FIRST_NAME, LAST_NAME
    		FROM EMPLOYEES
    			ORDER BY LAST_NAME, FIRST_NAME;
    	RETURN MONCURSEUR;
    END;
    Son utilisation dans SQL+ (ou autre) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    -- -----------------------------------------------------------------------
    -- Utilisation dans SQL+ de la fonction
    -- -----------------------------------------------------------------------
    SELECT f_lit_table FROM dual;


    2ème possibilité (procédure simple) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    -- -----------------------------------------------------------------------
    -- Procédure "autonome", sans utilisation de la fonction
    -- -----------------------------------------------------------------------
    CREATE OR REPLACE PROCEDURE sp_lit_table(parCurseur OUT types.curseur_type) AS
    BEGIN
    	-- Lecture du curseur
    	OPEN PARCURSEUR FOR 
    		SELECT DISTINCT FIRST_NAME, LAST_NAME 
    		FROM EMPLOYEES 
    		ORDER BY LAST_NAME, FIRST_NAME;
    END sp_lit_table;
    Son utilisation dans SQL+ (ou autre) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    -- -----------------------------------------------------------------------
    -- Utilisation dans SQL+ de la procédure
    -- -----------------------------------------------------------------------
    variable c refcursor
    	exec sp_lit_table (:c)
    	print c


    3ème possibilité (procédure qui englobe la 1ère fonction) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    -- -----------------------------------------------------------------------
    -- Ajout d'une procédure pour englober la fonction
    -- -----------------------------------------------------------------------
    CREATE OR REPLACE PROCEDURE SP_LIT_TABLE_2 (PARCURSEUR OUT SYS_REFCURSOR) AS
    BEGIN
      -- Lecture du curseur
      OPEN PARCURSEUR FOR
      SELECT F_LIT_TABLE()
      FROM DUAL;
    END SP_LIT_TABLE_2;
    Son utilisation dans SQL+ (ou autre) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    -- -----------------------------------------------------------------------
    -- Utilisation dans SQL+ de la procédure
    -- -----------------------------------------------------------------------
    variable c refcursor
    	exec sp_lit_table_2 (:c)
    	print c


    Voili, voilou...

    Bon c'est peut être trivial pour les habitués, mais pour les gens qui viennent d'autres bases de données ("MySQL" ou "SQL Server"/"Transact SQL" par exemple pour ne pas les nommer) le problème n'est pas des plus simples à résoudre (vu que dans les autres SGBD cela se fait de manière immédiate).

    J'aurais donc bien aimé trouver directement un exemple simple de ce type dans la FAQ...

    Si quelqu'un à un peu de temps dispo, libre à lui d'intégrer mon message dans la FAQ pour d'autres personnes....

  10. #10
    Membre habitué Avatar de ilalaina
    Homme Profil pro
    Inscrit en
    Mai 2007
    Messages
    341
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Madagascar

    Informations forums :
    Inscription : Mai 2007
    Messages : 341
    Points : 187
    Points
    187
    Par défaut
    Bonjour.
    Je relance la discussion parce que j'ai essaiéce que JCD a conseillé mais ça n'a pas marché.
    J'ai utilisé la première solution :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    CREATE OR REPLACE PACKAGE TYPES AS
    	-- Nouveau type de données de type "curseur"
    	TYPE CURSEUR_TYPE IS REF CURSOR;
    END TYPES;
    Le package est bien créé.
    Ensuite :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    CREATE OR REPLACE FUNCTION F_LIT_TABLE RETURN TYPES.CURSEUR_TYPE IS MONCURSEUR TYPES.CURSEUR_TYPE;
    BEGIN
    	-- Lecture de la table dans le curseur
    	OPEN MONCURSEUR FOR
    	  SELECT DISTINCT FIRST_NAME, LAST_NAME
    		FROM EMPLOYEES
    			ORDER BY LAST_NAME, FIRST_NAME;
    	RETURN MONCURSEUR;
    END;
    La fonction est bien créée.
    Et puis quand je fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT f_lit_table FROM dual;
    Ca me retourne l'erreur :
    ORA-00902: Type de données non valide
    En fait mon but c'est d'utiliser le résultat d'un curseur comme une table, c'est à dire pouvoir faire du genre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    select * from mon_curseur
    .

    J'utilise Oracle 8 pour information.

    Merci d'avance.
    " ... On naît, on vit, on meurt, mais exister est un honneur ... "

  11. #11
    jcd
    jcd est déconnecté
    Membre à l'essai
    Profil pro
    Inscrit en
    Février 2003
    Messages
    29
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2003
    Messages : 29
    Points : 19
    Points
    19
    Par défaut
    @ilalaina : Mes tests étaient effectués avec Oracle 10 XE, je pense que ton problème est lié à cette différence de version.
    Il me semble vaguement me souvenir avoir vu quelque chose sur la disponibilité de retour d'un ensemble d'enregistrements à partir de Oracle "N", mais je ne souviens plus ni où, ni quand, et je ne suis plus très sur de ce détail... ;-(

    Je te conseille de faire des recherches dans ce sens.
    Bon courage.

  12. #12
    Membre habitué Avatar de ilalaina
    Homme Profil pro
    Inscrit en
    Mai 2007
    Messages
    341
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Madagascar

    Informations forums :
    Inscription : Mai 2007
    Messages : 341
    Points : 187
    Points
    187
    Par défaut
    J'ai recherché tout l'après midi, mais je n'ai pas trouvé un moyen d'effectuer un retour de collection ou d'enregistrement avec Oracle 8.
    J'ai alors deux solutions :
    • Créer des tables temporaires.
    • Faire des Select imbriqués.
    Côté performance je crois que les Select imbriqués sont plus lourds pour la base, alors que si j'utilise des tables temporaires j'aurai du mal à declarer des curseurs appelant ces tables.

    Un conseil les experts?
    " ... On naît, on vit, on meurt, mais exister est un honneur ... "

  13. #13
    jcd
    jcd est déconnecté
    Membre à l'essai
    Profil pro
    Inscrit en
    Février 2003
    Messages
    29
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2003
    Messages : 29
    Points : 19
    Points
    19
    Par défaut
    J'ai effectué sur google une recherche rapide avec les termes : "pl/sql" recordset "oracle 8"

    A priori Oracle8 le permet, google m'a notamment retourné cette adresse :
    http://vbcity.com/page.asp?p=chapter...oks-wrox-vbora

    A creuser...

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 2
    Dernier message: 21/01/2015, 16h10
  2. copier une table d'une BDD dans une table d'une autre BDD
    Par faniette dans le forum C++Builder
    Réponses: 2
    Dernier message: 15/05/2013, 10h17
  3. [MySQL] requete dans une table avec une varible d'une autre table
    Par kogoi dans le forum PHP & Base de données
    Réponses: 7
    Dernier message: 03/11/2011, 15h24
  4. Copier les enregistrements d'une table vers une table d'une autre DB
    Par karinette21 dans le forum Requêtes et SQL.
    Réponses: 4
    Dernier message: 18/11/2008, 21h50
  5. Réponses: 6
    Dernier message: 30/08/2007, 16h47

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo