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 :

Tableau en paramètre à une fonction


Sujet :

PL/SQL Oracle

  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    209
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 209
    Par défaut Tableau en paramètre à une fonction
    Bonjour
    Environnement :
    Oracle 10
    Langage
    PLSQL
    Objectif :
    Passer a une fonction un tableau dynamique indexé
    Exemple de type
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    TYPE_LINE IS TABLE OF VARCHAR2(1024) INDEX BY BINARY_INTEGER;
    J’ai retenu la solution du tableau dynamique mais je suis ouvert a toutes propositions
    Du moment que je peux stocker plusieurs valeurs et les retrouver avec une indexation
    Exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Taleau(1) :=valeur ou  objet.tableau(1):=
    D’avance merci

  2. #2
    Membre éclairé Avatar de Jean_Benoit
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    499
    Détails du profil
    Informations personnelles :
    Âge : 71
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 499
    Par défaut
    Bonjour,

    J'ai essayé ceci:
    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
    declare
     
       type untabtype is table of varchar2(20) index by pls_integer;
       tt untabtype;
       procedure stockeuse ( z untabtype ) is
     
          begin
             dbms_output.put_line( 'Depuis la procedure: ' || z(0) );
          exception
             when others then
                dbms_output.put_line( 'Exc inner: ' || sqlerrm );
          end;
     
    begin
       tt(0) := 'A';
       stockeuse( tt );
       dbms_output.put_line( 'Resultat depuis l appelant: ' ||  tt(0) );
    exception
       when others then
          dbms_output.put_line( 'Exc outer: ' || sqlerrm );
    end;
    Dans ce cas le type tableau est visible depuis la procédure interne.
    Si tu veux une procédure autonome, il faut déclarer le type tableau dans les specs d'un package et créer la procédure dans le body du même package.

  3. #3
    Membre éclairé
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    209
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 209
    Par défaut Merci mais pas trop vite que je puisse suivre ...
    Bonjour
    Pas trop vite .
    Voici quelquels infos :
    1)Je cherche effectivement a rendre ma fonction indépendante et autonome
    (j’aurais du le précisé) nous ne sommes donc pas dans le cas (trop simple) d’un appel depuis une procédure en interne

    2)J’ai cherché a créer un type en faisant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    create or replace
    type tab2D2 IS TABLE OF VARCHAR2(1024) INDEX BY BINARY_INTEGER;
    Le probleme
    Si je cherche a compiler j’ai le message suivant
    PLS-00255 : Utilisation de la table pl/SQL non autorisé dans ce contexte

    Tu dit : il faut déclarer le type tableau dans les specs d'un package et créer la procédure dans le body du même package.

    Question : les specs d'un package ?
    le body du même package ?
    vous auriez un exemple ?
    Merci

  4. #4
    Membre éclairé
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    209
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 209
    Par défaut Les packages PL/SQL se divisent en 2 parties :
    Les packages PL/SQL se divisent en 2 parties :

    la spécification (les spec) : Partie déclarative du package qui liste les entêtes de procédures et fonctions (contenues dans le package PL/SQL).

    le corps du package (le body): possède le code PL/SQL des procédures et fonctions définies dans la spécification.

    Syntaxe
    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
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    CREATE [OR REPLACE] PACKAGE BODY nompackage
    { IS | AS }
    --Déclarations de variables locales
    --Corps des sous-programmes publics et privés
    BEGINEND [nompackage] ;
     
    Exemple en code
    view sourceprint?
    01.-- 1) Installation d'un package 
    02.CREATE or replace PACKAGE pacRH 
    03.AS
    04.-- ===================== 
    05./* 
    06. 
    Fonction de conversion en FF (arrondir aux centimes) d'un montant transmis en EURO. 
    07.*/ 
    08. 
    FUNCTION ConvFF (pMontant NUMBER) RETURN NUMBER ; 
    09. 
     
    10.END pacRH ; 
    11. 
     
    12.-- 2) Implémentation du corps de package 
    13.CREATE or replace PACKAGE BODY pacRH 
    14.AS
    15. 
     
    16.-- ===================== 
    17.FUNCTION ConvFF (pMontant NUMBER) 
    18.RETURN NUMBER 
    19.IS
    20. 
    vTaux  CONSTANT NUMBER := 6.55957 ; 
    21.BEGIN
    22. 
    RETURN ( ROUND( pMontant * vTaux, 2) ) ; 
    23.EXCEPTION 
    24. 
    WHEN others THEN RETURN (null) ; 
    25.END ConvFF ; 
    26. 
     
    27.END pacRH ; 
    28. 
     
    29.-- ======================================= 
    30.-- Test 
    31.select * from salarie 
    32.where pacRH.ConvFF(sal) > 12000 ; 
    33. 
     
    34.-- =======================================


    Avec cela nous y voyons plus claire
    Je sais ce que c'est q'un package
    ou se trouve le spec le body.
    Mais auriez vous un petit exemple pour comprendre l'explication ?
    "il faut déclarer le type tableau dans les specs d'un package et créer la procédure dans le body du même package"
    d'avance merci

  5. #5
    Membre éclairé Avatar de Jean_Benoit
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    499
    Détails du profil
    Informations personnelles :
    Âge : 71
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 499
    Par défaut
    Il existe des types prédéfinis dans Oracle, par exemple VARCHAR2.
    On peut créer un nouveau type, mais il faut le placer dans la spec d'un package.

    Exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    create or replace
    package jbmtabarg 
    authid current_user
    as
     
    type tab_type_example is table of varchar2(30) index by pls_integer;
     
    function mademo( argun in number ) return number;
     
    end jbmtabarg;
    Ensuite pour accéder au type en dehors de ce package, il faut préfixer le nom du type par le nom du package.

    Exemple d'utilisation d'un type custom dans le pl/sql d'un trigger ORACLE FORMS:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    declare
    	lv_var varchar2(5) := '---';
    	ln_var number(6) := 0;
    	tt jbmtabarg.tab_type_example;
    begin
    	tt(0) := 1;
    	tt(1) := 2;
     
       ln_var := f_test_tableau( tt ); 
       :block3.lv_message := :block3.lv_message || ' - ' || to_char( ln_var );
    exception
    	when others then
    	   message( 'Exc en WBP tableau: ' || sqlerrm );
    end;
    Mais il faut faire attention car la ligne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    tt jbmtabarg.tab_type_example;
    charge tout le package en mémoire (je crois que c'est dans la library cache).

    Pour en arriver à ta demande initiale, voici une fonction qui reçoit en argument une variable de type tableau:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    FUNCTION f_test_tableau( zz  jbmtabarg.tab_type_example) RETURN number IS
     
    BEGIN
      return zz(0) * 4 ;
    END;
    Hope this helps

  6. #6
    Membre Expert
    Inscrit en
    Août 2009
    Messages
    1 073
    Détails du profil
    Informations forums :
    Inscription : Août 2009
    Messages : 1 073
    Par défaut
    Citation Envoyé par Jean_Benoit Voir le message
    Il existe des types prédéfinis dans Oracle, par exemple VARCHAR2.
    On peut créer un nouveau type, mais il faut le placer dans la spec d'un package.
    À noter que s'il n'y a besoin d'avoir que des tableaux "consécutifs" (ie, pas de trous ; et ça suffit très souvent), on peut utiliser une Nested Table. Auquel cas, la déclaration du type peut se faire en dehors d'un package, au niveau schéma (il suffit d'omettre le index by).

  7. #7
    Membre éclairé Avatar de Jean_Benoit
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    499
    Détails du profil
    Informations personnelles :
    Âge : 71
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 499
    Par défaut
    Effectivement je ne connaissais pas mais j'ai trouvé des infos:

    Création du type:
    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 type CourseList as table of varchar2(64)
     
    CREATE TABLE jbmdepartment (
    name     VARCHAR2(20),
    director VARCHAR2(20),
    office   VARCHAR2(20),
    courses  CourseList)
    NESTED TABLE courses STORE AS courses_tab;
     
    select cardinality ( courses ) from jbmdepartment
     
    INSERT INTO jbmdepartment
    (name, director, office, courses)
    VALUES
    ('English', 'Lynn Saunders', 'Breakstone Hall 205', CourseList(
    'Expository Writing',
    'Film and Literature',
    'Modern Science Fiction',
    'Discursive Writing',
    'Modern English Grammar',
    'Introduction to Shakespeare',
    'Modern Drama',
    'The Short Story',
    'The American Novel'));
     
    commit
    Création du package spec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    create or replace
    package jbmtabarg 
    authid current_user
    as
     
    type tab_type_example is table of varchar2(30) index by pls_integer;
     
    procedure testnested ( pcourse in courselist );
     
    function mademo( argun in number ) return number;
     
    end jbmtabarg;
    Création du package body:
    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 body jbmtabarg 
    as
     
    procedure testnested ( pcourse in courselist ) is
     
    begin
       UPDATE jbmdepartment
       SET courses = pcourse
       WHERE name = 'English';
     
    exception
    when others then
       dbms_output.put_line( 'Exc en proc neste: ' || sqlerrm );
    end testnested;
     
     
     
    function mademo( argun in number) 
    return number
    is
    begin
       return argun * 3;
    end mademo;
     
    end jbmtabarg;
    Utilisation du package en passant le type en argument à une procédure:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    declare
       lc courselist := courselist( 'Maths', 'Géo', 'Gym' );
    begin
       dbms_output.put_line( 'Début' );
       jbmtabarg.testnested( lc);
    exception
       when others then
          dbms_output.put_line( 'Exc en nested: ' || sqlerrm );
    end;
    Résultat des courses (list):
    "NAME" "DIRECTOR" "OFFICE" "COURSES"
    "English" "Lynn Saunders" "Breakstone Hall 205" SOVENTE.COURSELIST(Maths,Géo,Gym)
    Je ne sais pas si j'ai bon?

Discussions similaires

  1. Réponses: 6
    Dernier message: 04/12/2012, 19h04
  2. Réponses: 0
    Dernier message: 15/06/2010, 10h58
  3. paramètrer une fonction avec un tableau de deux dimensions
    Par dark_geek dans le forum VB 6 et antérieur
    Réponses: 2
    Dernier message: 22/02/2010, 14h01
  4. Passer en paramètre un tableau php dans une fonction javascript
    Par hartecel dans le forum Général JavaScript
    Réponses: 9
    Dernier message: 17/07/2008, 15h17
  5. passage de tableau 2D a une fonction
    Par watashinoitadakimasu dans le forum C
    Réponses: 2
    Dernier message: 11/09/2003, 02h33

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