Developpez.com - 4D
X

Choisissez d'abord la catégorieensuite la rubrique :


4D For OCI et la lecture des méta-données

Par Noreddine MARGOUM (Technicien Contrôle Qualité, 4D S.A.)
 

Cette note technique a pour but de vous montrer l'utilisation de la commande OCIDescribeAnyText du plug-in 4D For OCI, pour lire des métadonnées. On entend par métadonnée la description des objets Oracle. Pour une table ou une vue, par exemple, on décrira l'ensemble des colonnes (champs), pour lire le nom et le type de chaque colonne.

I. Introduction
II. Présentation de la commande
Table
Vue
Procédure
Fonction
Package
Type
Synonyme
Séquence
Schéma
Base de données
III. Mise en oeuvre de la commande OCIDescribeAnyText
Méthode de sélection des objets à décrire
Sélection des objets à décrire
Sélection des tables
Sélection des vues
Sélection des procédures
Sélection des fonctions
Sélection des packages
Méthodes de description des objets
Méthode de description d'une table ou d'une vue
Méthode de description d'un sous-programme (procédure ou fonction)
Méthode de description d'un package
IV. Utilisation de la base de test
V. Conclusion
VI. Base exemple


I. Introduction

Cette note technique a pour but de vous montrer l'utilisation de la commande OCIDescribeAnyText du plug-in 4D For OCI, pour lire des métadonnées. On entend par métadonnée la description des objets Oracle. Pour une table ou une vue, par exemple, on décrira l'ensemble des colonnes (champs), pour lire le nom et le type de chaque colonne.


II. Présentation de la commande

Voici l'interface de la commande :

OCIDescribeAnyText (svchp;errhp;NomObjet;LongObjet;NiveauInfo;TypeObjet;dschp) -> Entier long

Paramètre Type Description
svchp Entier long Handle contexte (service context handle). Doit être alloué avant l’appel de la commande.
errhp Entier long Handle erreur (error handle) Doit être alloué avant l’appel de la commande.
NomObjet Texte Libellé de l’objet à décrire. Peut être un nom de table, de vue...
LongObjet Entier long Représente la longueur de l’objet. Passez la valeur 1.
NiveauInfo Entier long Paramètre réservé pour de futures extensions. Passez la constante OCI_DEFAULT.
TypeObjet Entier long Type de l’objet à décrire. Peut recevoir les valeurs données dans la description de la commande(*).
dschp Entier long Handle descripteur (OCI_HTYPE_DESCRIBE). Doit être alloué avant l’appel de la commande.
Résultat Entier long Code retour de la commande égal à OCI_SUCCESS (0) en cas de succès, ou OCI_ERROR (-1) en cas d’erreur.


(*) Voici la liste des valeurs des types d'objets (paramètre TypeObjet) susceptibles d'être décrits. Les constantes correspondantes n'existent pas dans 4D For OCI. Il faudra donc passer les valeurs :

Constante Valeur Objet
OCI_PTYPE_UNK 0 Objet inconnu
OCI_PTYPE_TABLE 1 Table
OCI_PTYPE_VIEW 2 Vue
OCI_PTYPE_PROC 3 Procédure
OCI_PTYPE_FUNC 4 Fonction
OCI_PTYPE_PKG 5 Package
OCI_PTYPE_TYPE 6 Type
OCI_PTYPE_SYN 7 Synonyme
OCI_PTYPE_SEQ 8 Séquence
OCI_PTYPE_SCHEMA 17 Schéma
OCI_PTYPE_DATABASE 18 Base de données


La commande OCIDescribeAnyText permet donc de décrire tous ces objets.

Voici une brève présentation de ces objets ainsi que quelques informations, non exhaustives, que la commande peut lire :


Table

La table, dans le même sens que la table 4D, contient les données utilisateur. La table est constituée de colonnes, dans le même sens qu'un champ d'une table 4D.

Liste des informations (non exhaustive) que peut lire la commande :

Information Type Description
OCI_ATTR_NUM_COLS Entier long Nombre de colonnes (champs) de la table.
OCI_ATTR_LIST_COLUMNS Entier long Handle sur la liste des colonnes. Ce handle a lui-même un certain nombre d’informations qui lui sont rattachées (nombre d’éléments de la liste (OCI_ATTR_NUM_PARAM), etc...).
OCI_ATTR_PTYPE Entier long Code indiquant s’il s’agit d’une table (= 1) ou d’une vue (= 2).


Pour une colonne donnée (référencée par un handle), on peut lire les informations suivantes :

Information Type Description
OCI_ATTR_NAME Texte Nom de la colonne (champ).
OCI_ATTR_DATA_TYPE Entier long Code indiquant le type de donnée Oracle.

Vue

Une vue est une sorte de fenêtre, d'aperçu, sur une table. Une vue peut ainsi pointer sur plusieurs tables. Il n'y a pas de duplication de donnés, et la vue est simplement stockée comme un SELECT ayant un nom.

Liste des informations (non exhaustive) que peut lire la commande pour l'objet vue :

info Note : Voir la Liste des informations pour l'objet Table (paragraphe précédent).

Procédure

Une procédure est un programme stocké, écrit en PL/SQL.

Liste des informations (non exhaustive) que peut lire la commande pour l'objet procédure :

Information Type Description
OCI_ATTR_LIST_ARGUMENTS Entier long Handle sur la liste des arguments de la procédure. Ce handle a lui-même un certain nombre d’informations qui lui sont rattachées (nombre d’éléments de la liste (OCI_ATTR_NUM_PARAMS), etc...).
Pour chaque paramètre de la procédure, on peut lire le même type d'informations que pour la colonne d'une table, à savoir le nom et le type du paramètre (voir l'objet 'Table').


Fonction

Une fonction est un programme stocké, écrit en PL/SQL, et qui retourne une valeur.

Liste des informations (non exhaustive) que peut lire la commande pour l'objet fonction :

info Note : Voir la Liste des informations pour l'objet Procédure (paragraphe précédent).

Package

Un package est un ensemble qui encapsule des procédures et des fonctions, ainsi que certaines données. Le package est constitué de 2 parties, une partie spécification qui est la partie déclarative des objets du package et une partie corps qui contient l'implémentation de ces objets.

Liste des informations (non exhaustive) que peut lire la commande pour l'objet package :

Information Type Description
OCI_ATTR_LIST_SUBPROGRAMS Entier long Handle sur la liste des sous-programmes (procédures et fonctions). Ce handle a lui-même un certain nombre d’informations qui lui sont rattachées (nombre d’éléments de la liste (OCI_ATTR_NUM_PARAMS), etc...).
OCI_ATTR_PTYPE Entier long Code indiquant s’il s’agit d’un package (= 5).


Pour un sous-programme donné (référencé par un handle), on peut lire les informations suivantes :

Information Type Description
OCI_ATTR_NAME Texte Nom du sous-programme.
OCI_ATTR_PTYPE Entier long Code indiquant s’il s’agit d’une procédure (= 3) ou d’une fonction (= 4).


Pour les informations sur les paramètres du sous-programme, consulter les explications données pour les objets 'Procédure' ou 'Fonction'.


Type

En plus des types prédéfinis (VARCHAR, NUMBER...), l'utilisateur peut définir ses propres types constitués à partir de ces types de base ou de types existant plus complexes, comme les collections de type Tableau (VARRAY) ou Table (NESTED TABLE).

Liste des informations (non exhaustive) que peut lire la commande pour l'objet type :

Information Type Description
OCI_ATTR_VERSION Texte Chaîne contenant la version du type, telle que définie par le créateur du type.
OCI_ATTR_NUM_TYPE_ATTRS Entier long Nombre d’attributs que contient le type.
OCI_ATTR_PTYPE Entier long Code indiquant s’il s’agit d’un type (= 6).
info Point important : Pour décrire l'objet Type, il est impératif d'initialiser l'environnement OCI en mode objet.

L'appel suivant doit donc être effectué :
$status:=OCIEnvCreate (envhp;OCI_OBJECT)

Synonyme

Dans le même sens qu'a ce mot dans une langue donnée, il définit un nom alternatif donné à un objet (table, vue...)

Liste des informations (non exhaustive) que peut lire la commande pour l'objet synonyme :

Information Type Description
OCI_ATTR_SCHEMA_NAME Texte Chaîne contenant le nom du schéma du nom original dont dérive le synonyme.
OCI_ATTR_NAME Texte Chaîne contenant le nom original dont dérive le synonyme.
OCI_ATTR_PTYPE Entier long Code indiquant s’il s’agit d’un synonyme (= 7).

Séquence

Une séquence est une suite de nombres entiers. Cette suite est régie par certains paramètres (valeur de départ, valeur d'incrémentation...). La séquence sert à la génération de clés uniques pour la colonne d'une table, ou simplement de compteur.

Liste des informations (non exhaustive) que peut lire la commande pour l'objet séquence :

Information Type Description
OCI_ATTR_MIN Entier long Valeur minimum du compteur.
OCI_ATTR_MAX Entier long Valeur maximum du compteur.
OCI_ATTR_INCR Entier long Valeur d’incrémentation du compteur.
OCI_ATTR_PTYPE Entier long Code indiquant s’il s’agit d’une séquence (= 8).

Schéma

C'est l'ensemble des données liées à un utilisateur, par exemple "Scott".

Liste des informations (exhaustive) que peut lire la commande pour l'objet schéma :

Information Type Description
OCI_ATTR_LIST_OBJECTS Entier long Handle sur la liste des objets appartenant au schéma.
OCI_ATTR_PTYPE Entier long Code indiquant s’il s’agit d’un schéma (= 17).
info Remarque : on peut voir ici qu'à partir d'un objet schéma, on peut atteindre l'ensemble des objets de ce schéma.

Base de données

C'est l'ensemble de tous les schémas.

Liste des informations (non exhaustive) que peut lire la commande pour l'objet base de données :

Information Type Description
OCI_ATTR_VERSION Texte Version de la base de données.
OCI_ATTR_LIST_SCHEMAS Entier long Handle sur la liste des schémas de la base de données.
OCI_ATTR_PTYPE Entier long Code indiquant s’il s’agit d’une base de données (= 18).
info Remarque 1 : on peut voir ici qu'à partir d'un objet base de données, on peut atteindre l'ensemble des schémas et ainsi l'ensemble de tous les objets de tous les schémas (voir la remarque donnée pour l'objet schéma).
info Remarque 2 : d'après la remarque 1, cette structure arborescente (base de données -> schémas -> objets) permet d'écrire un programme général de lecture des métadonnées de tous les objets d'une base de données Oracle.

III. Mise en oeuvre de la commande OCIDescribeAnyText

Après avoir présenté la commande et les objets qu'elle peut décrire, nous allons vous montrer, au travers de quelques descriptions d'objets, l'utilisation de cette commande dans 4D For OCI. Nous allons détailler le code à utiliser pour décrire une table, une vue, dont le code pour ces 2 objets est similaire, ainsi que pour les packages, les procédures et les fonctions. Pour le reste des objets, leur description n'est pas donnée dans cette note, dans la mesure où nous pensons qu'elle peut se faire en s'appuyant sur le modèle proposé ici.


Méthode de sélection des objets à décrire

La méthode générique ci-après nous permet de sélectionner les objets que nous allons décrire.

La méthode effectue un simple appel à la requête SQL SELECT sur la table adéquate contenant la liste des objets.

    `OCI_SELECT_OBJECT

    C_POINTEUR($1) `pointeur pour le define pour récupérer les valeurs de la colonne
    C_TEXTE(${2}) `colonne et table de la requête, et éventuellement clause WHERE
    C_TEXTE($requete_sql) `libellé de la requête SQL
    C_ENTIER LONG($status) `code retour des commandes OCI
    C_ENTIER LONG($errhp) `handle-erreur
    C_ENTIER LONG($stmthp) `handle- requête
    C_ENTIER LONG($define) `handle-define

    C_TEXTE(vt_temp) `variable pour récupérer temporairement les données résultat
    C_ENTIER LONG(null_ind1;null_ind2;null_ind3) `variables indicateurs

    `construction de la requête SELECT
    $requete_sql:="SELECT "+$2+" FROM "+$3
    `éventuellement une clause WHERE
    Si (Nombre de parametres=4)
       $requete_sql:=$requete_sql+" "+$4
    Fin de si

    `allocation du handle-requête
    $status:=OCIHandleAlloc(envhp;$stmthp;OCI_HTYPE_STMT)

    `allocation du handle-erreur
    $status:=OCIHandleAlloc(envhp;$errhp;OCI_HTYPE_ERROR)

    `affectation du libellé de la requête SQL au handle-requête
    $status:=OCIStmtPrepare($stmthp;$errhp;$requete_sql;OCI_DEFAULT)

    `variables-indicateurs pour la commande OCIDefineByPos().
    `Les informations retournées par ces variables sont inutiles dans notre exemple.
    `ces variables servent notamment à savoir s'il y a des valeurs NULL, tronquées.
    null_ind1:=0
    null_ind2:=0
    null_ind3:=0

    `réalisation du Define avec l'unique colonne de la requête
    $status:=OCIDefineByPos($stmthp;$define;$errhp;1;->vt_temp;SQLT_STR;->null_ind1;->null_ind2;->null_ind3;OCI_DEFAULT)

    `exécution de la requête SQL
    $status:=OCIStmtExecute (svchp;$stmthp;$errhp;1;0;0;0;OCI_DEFAULT )

    `traitement du résultat : on affecte le résultat au tableau passé en premier paramètre
    Tant que($status#OCI_NO_DATA )
       AJOUTER A TABLEAU($1->;vt_temp)
       $status:=OCIStmtFetch($stmthp;$errhp;1)
    Fin tant que

    `libération du handle-requête
    $status:=OCIHandleFree($stmthp)
    `libération du handle-erreur

    $status:=OCIHandleFree($errhp)


Sélection des objets à décrire

Pour sélectionner les objets que nous allons décrire, nous allons donc appliquer la méthode OCI_SELECT_OBJECT présentée dans le point précédent. La liste des objets est remontée dans le tableau passé en premier paramètre. On fournit à la méthode les noms de la colonne et de la table contenant la liste de ces objets.


Sélection des tables

    `SELECT table_name FROM user_tables

    OCI_SELECT_OBJECT (->tt_Tables;"table_name";"user_tables")


Sélection des vues

    `SELECT view_name FROM user_views

    OCI_SELECT_OBJECT (->tt_Views;"view_name";"user_views")


Sélection des procédures

    `SELECT DISTINCT name FROM user_source WHERE Type='PROCEDURE'

    OCI_SELECT_OBJECT (->tt_Procedures;"distinct name";"user_source";"WHERE Type='PROCEDURE'")


Remarquez l'utilisation de la clause WHERE pour ne remonter que les objets de type procédure, et éviter notamment la remontée des noms de fonctions. Nous avons aussi utilisé l'option DISTINCT du SELECT pour ne remonter que des noms uniques.


Sélection des fonctions

    `SELECT distinct name FROM user_source WHERE Type='FUNCTION'

    OCI_SELECT_OBJECT (->tt_Functions;"distinct name";"user_source";"WHERE Type='FUNCTION'")


Remarquez l'utilisation de la clause WHERE pour ne remonter que les objets de type fonction, et éviter notamment la remontée des noms de procédures. Nous avons aussi utilisé l'option DISTINCT du SELECT pour ne remonter que des noms uniques.


Sélection des packages

    `SELECT object_name FROM user_objects WHERE object_type='PACKAGE'

    OCI_SELECT_OBJECT (->tt_Packages;"object_name";"user_objects";"WHERE object_type='PACKAGE'")


Méthodes de description des objets


Méthode de description d'une table ou d'une vue

    `OCI_DESCRIBE_TABLE_OR_VIEW

    C_TEXTE($1) `nom de la table ou de la vue à décrire
    C_ENTIER LONG($2) `1 (OCI_PTYPE_TABLE) : description de la table
    `2 (OCI_PTYPE_VIEW) : description de la vue:
    C_POINTEUR(${3}) `pointeurs sur les tableaux des noms et types de colonnes
    C_ENTIER LONG($status) `code retour de la fonction OCI
    C_ENTIER LONG($dschp) `handle descripteur
    C_ENTIER LONG($collsth) `handle pour la liste des colonnes
    C_ENTIER LONG($colh) `handle colonne
    C_ENTIER LONG($paramh) `handle paramètre
    C_ENTIER LONG($index;$nb_columns) `nombre de colonnes
    C_TEXTE($name_column) `nom d'une colonne
    C_ENTIER LONG($dtype_column) `code du type de donnée d'une colonne
    C_TEXTE($lib_dtype_column) `libellé du type de donnée de la colonne

    `allocation du handle descripteur
    $status:=OCIHandleAlloc (envhp;$dschp;OCI_HTYPE_DESCRIBE)
    `1 : OCI_PTYPE_TABLE (pour une table), 2 : OCI_PTYPE_VIEW (pour une vue)
    $status:=OCIDescribeAnyText (svchp;errhp;$1;1;OCI_DEFAULT;$2;$dschp)
    `récupération du `handle paramètre $paramh, attribut du handle descripteur $dschp
    $status:=OCIAttrGetVal ($dschp;$paramh;OCI_ATTR_PARAM;errhp)
    `récupération du nombre de colonnes de la table
    $status:=OCIAttrGetVal ($paramh;$nb_columns;OCI_ATTR_NUM_COLS;errhp)
    `récupération du handle liste des colonnes $collsth
    $status:=OCIAttrGetVal ($paramh;$collsth;OCI_ATTR_LIST_COLUMNS;errhp)

    Si ($nb_columns>0)
       `boucle sur les colonnes
       Boucle ($index;1;$nb_columns)
          `récupération du handle colonne $colh
          $status:=OCIParamGet ($collsth;errhp;$colh;$index)
          `nom de la colonne
          $status:=OCIAttrGetText($colh;$name_column;OCI_ATTR_NAME;errhp)
          `type de la colonne
          $status:=OCIAttrGetVal($colh;$dtype_column;OCI_ATTR_DATA_TYPE;errhp)  
          `récupération du libellé du type de donnée de la colonne avec le code du type
          $lib_dtype_column:=OCI_Lib_External_Type($dtype_column)  
          `inscrire le nom de la colonne
          AJOUTER A TABLEAU($3->;$name_column)
          `inscrire le libellé du type de la colonne
          AJOUTER A TABLEAU($4->;$lib_dtype_column)  
       Fin de boucle
    Fin de si



Commentaires sur la méthode :

La méthode commence par allouer un handle-descripteur en utilisant la commande OCIHandleAlloc à laquelle on spécifie le type de handle souhaité (OCI_HTYPE_DESCRIBE). On associe ensuite le libellé de l'objet à décrire (texte) ainsi que son type (entier) à ce handle-descripteur.



Ensuite, on récupère le handle-paramètre (commande OCIAttrGetVal) qui pointe sur la description de l'objet, description qui se présente de manière arborescente.

Il est à noter que toute la description de l'objet est transférée sur le client à l'appel de la commande OCIDescribeAnyText. Les appels ultérieurs des autres commandes pour récupérer les informations sur la description de l'objet ne consomment donc pas de ressources réseau.

A partir du handle-paramètre, on peut lire le nombre de colonnes de la table (ou de la vue), mais aussi récupérer le handle-liste qui contient les informations sur la liste des colonnes.

A partir de ce handle-liste, on récupérera un handle-colonne, via la commande OCIParamGet, qui pointera donc sur une colonne particulière. On pourra alors lire toutes les informations sur une colonne, comme son libellé ou son type.



Le type d'une colonne est retourné sous forme de code entier, que nous traduisons en texte avec la méthode projet OCI_Lib_External_Type. Cette méthode projet effectue une conversion du code entier reçu en texte représentant le type de données Oracle correspondant. Voici le tableau (non exhaustif) correspondant à cette transformation :

Code entier reçu Constante OCI correspondante Libellé Oracle du type
1 SQLT_CHR VARCHAR2
2 SQLT_NUM NUMBER
3 SQLT_INT 8 or16 or 32 bits signed INTEGER
4 SQLT_FLT FLOAT
5 SQLT_STR Null-terminated STRING
6 SQLT_VNU VARNUM
8 SQLT_LNG LONG
9 SQLT_VCS VARCHAR
11 SQLT_RID ROWID
12 SQLT_DAT DATE
15 SQLT_VBI VARRAW
23 SQLT_BIN RAW
24 SQLT_LBI LONG RAW
68 SQLT_UIN UNSIGNED INT
94 SQLT_LVC LONG VARCHAR

Méthode de description d'un sous-programme (procédure ou fonction)

    `OCI_DESCRIBE_SUBPROGRAM

    C_TEXTE($1) `nom du sous-programme (procédure ou fonction) à décrire
    C_ENTIER LONG($2) `Description d'une procédure ou d'une fonction ?
    `3 : OCI_PTYPE_PROC, 4 : OCI_PTYPE_FUNC
    C_POINTEUR(${3})  `listes des paramètres de la procédure et leurs types
    C_ENTIER LONG($status)  `code retour de la fonction OCI
    C_ENTIER LONG($count;$startloop;$endloop)
    C_ENTIER LONG($dschp)  `handle descripteur
    C_ENTIER LONG($paramh)  `handle paramètre
    C_ENTIER LONG($args_listh)  `handle sur la liste des paramètres du sous-programme
    C_ENTIER LONG($argh)  `handle sur un paramètre du sous-programme
    C_ENTIER LONG($args_num)  `nombre de paramètres du sous-programme
    C_ENTIER LONG($arg_type)  `type du paramètre du sous-programme
    C_TEXTE($arg_name)  `nom du paramètre du sous-programme

    $status:=OCIHandleAlloc (envhp;$dschp;OCI_HTYPE_DESCRIBE)
    $status:=OCIDescribeAnyText (svchp;errhp;$1;1;OCI_DEFAULT;$2;$dschp)
    `$2=3 :OCI_PTYPE_PROC, $2=4 : OCI_PTYPE_FUNC
    $status:=OCIAttrGetVal ($dschp;$paramh;OCI_ATTR_PARAM;errhp)
    $status:=OCIAttrGetVal ($paramh;$args_listh;OCI_ATTR_LIST_ARGUMENTS;errhp)
    $status:=OCIAttrGetVal ($args_listh;$args_num;OCI_ATTR_NUM_PARAMS;errhp)
    Au cas ou
       : ($2=4) `Fonction
          $startloop:=0
          $endloop:=$args_num-1
       : ($2=3) `Procédure
          $startloop:=1
          $endloop:=$args_num
       Sinon
          $endloop:=0
          $endloop:=0
    Fin de cas
    Boucle ($count;$startloop;$endloop)
       $status:=OCIParamGet ($args_listh;errhp;$argh;$count)
       `récupération du nom du paramètre
       $status:=OCIAttrGetText ($argh;$arg_name;OCI_ATTR_NAME;errhp)
       ` récupération du type du paramètre
       status:=OCIAttrGetVal ($argh;$arg_type;OCI_ATTR_DATA_TYPE;errhp)
       AJOUTER A TABLEAU($3->;$arg_name)
       AJOUTER A TABLEAU($4->;OCI_Lib_External_Type($arg_type))
    Fin de boucle



Commentaires sur la méthode :

De la même manière que pour la méthode de description d'un objet table ou vue, il faut allouer le handle-descripteur auquel on associe l'objet à décrire. On récupère le handle-paramètre (commande OCIAttrGetVal). A partir du handle-paramètre, on récupère le handle sur la liste des arguments de la fonction ou de la procédure (commande OCIAttrGetVal).

Du handle sur la liste des arguments, on lit le nombre des arguments (paramètres) du sous-programme (commande OCIAttrGetVal).

La position des paramètres d'une fonction commence à zéro, qui est le paramètre retourné par la fonction. La position des paramètres pour une procédure commence à 1. Ceci explique l'utilisation de la boucle paramétrée sur la liste des arguments, boucle qui peut commencer à 0 ou à 1 selon le type de sous-programme (fonction ou procédure). Ensuite, avec le handle d'un paramètre donné sur le sous-programme, on lit le nom du paramètre (OCIAttrGetText) ainsi que son type (OCIAttrGetVal). Le type de l'argument est un entier que nous traduisons en utilisant la méthode OCI_Lib_External_Type, méthode détaillée dans la description d'un objet de type table ou vue.


Méthode de description d'un package

    `OCI_DESCRIBE_PACKAGE

    C_TEXTE($1) `nom du package à décrire
    C_POINTEUR($2) `liste des handles (références) pour chacun des sous-programmes. Utile
    `pour retrouver la liste des paramètres de chaque sous-programme
    C_POINTEUR($3) `liste des types des sous-programmes (procédures & fonctions) à
    `récupérer. 'P' pour Procédure et 'F' pour Fonction
    C_POINTEUR($4) `liste de sous-programmes (procédures & fonctions) à récupérer
    C_ENTIER LONG($status) `code retour de la fonction OCI
    C_ENTIER LONG($count;$endloop)
    C_ENTIER LONG($dschp) `handle descripteur
    C_ENTIER LONG($paramh)  `handle paramètre
    C_ENTIER LONG($progs_listh) `handle sur la liste des sous-programmes
    C_ENTIER LONG($progh) `handle sur un sous-programme
    C_ENTIER LONG($progs_num) `nombre de sous-programmes
    C_TEXTE($prog_name) `nom du sous-programme
    C_ENTIER LONG($prog_type) `type du sous-programme, type = 3 alors procédure,
    `type = 4 alors fonction

    $status:=OCIHandleAlloc(envhp;$dschp;OCI_HTYPE_DESCRIBE)
    `5: OCI_PTYPE_PKG
    $status:=OCIDescribeAnyText(svchp;errhp;$1;1;OCI_DEFAULT;5;$dschp)
    $status:=OCIAttrGetVal($dschp;$paramh;OCI_ATTR_PARAM;errhp)
    $status:=OCIAttrGetVal($paramh;$progs_listh;OCI_ATTR_LIST_SUBPROGRAMS; errhp)
    `récupération du handle sur la liste des sous-programmes
    $status:=OCIAttrGetVal($progs_listh;$progs_num;OCI_ATTR_NUM_PARAMS;errhp) `récupération du nombre de sous-programmes
    $endloop:=$progs_num-1
    Boucle ($count;0;$endloop)
       `récupération du handle sur un sous-programme
       $status:=OCIParamGet($progs_listh;errhp;$progh;$count)
       `récupération du nom du sous-programme
       $status:=OCIAttrGetText($progh;$prog_name;OCI_ATTR_NAME;errhp)
       `récupération du type du sous-programme
       $status:=OCIAttrGetVal($progh;$prog_type;OCI_ATTR_PTYPE;errhp)
       AJOUTER A TABLEAU($2->;$progh) `stocker le handle sur le sous-programme
       Au cas ou
          :($prog_type=3) `le sous-programme est une Procédure. Mettre 'P'
             AJOUTER A TABLEAU($3->;"P")
          :($prog_type=4) `le sous-programme est une Fonction. Mettre 'F'
             AJOUTER A TABLEAU($3->;"F")
       Fin de cas
       AJOUTER A TABLEAU($4->;$prog_name) `stocker le nom du sous-programme
    Fin de boucle



Commentaires sur la méthode :

La méthode commence par allouer le handle-descripteur, auquel on associe le nom du package à décrire.

Du handle-descripteur, on récupère le handle-paramètre $paramh (commande OCIAttrGetVal).

Du handle paramètre $paramh, on récupère le handle sur la liste des sous-programmes $progs_lish (commande OCIAttrGetVal).

Du handle $progs_listh, on lit le nombre de sous-programmes ($progs_num) sur lequel on effectue une boucle (commande OCIAttrGetVal).

Dans la boucle sur les sous-programmes, on récupère le handle sur un sous-programme donné (commande OCIParamGet), en fournissant le handle sur la liste des sous-programmes et la position du sous-programme dans la liste. Il est important de noter que la position d'un sous-programme dans la liste des sous-programmes, commence à zéro, comme pour la liste des arguments d'une fonction.

A partir du handle sur un sous-programme donné, on lit le nom et le type (fonction ou procédure) du sous-programme. Ces informations, ainsi que le handle sur le sous-programme sont stockés dans des tableaux pour être utilisés en dehors de cette méthode, afin de récupérer la liste des arguments de chaque sous-programme, ainsi que des informations qui s'y rattachent (nom et type de l'argument).


IV. Utilisation de la base de test

La base de test, construite en 4D 2004, contient l'implémentation des différentes méthodes présentées ici. Elle est très simple à utiliser.


En mode structure, vous devez adapter la méthode OCI_CONNEXION.

Dans cette méthode, modifier les paramètres de connexion (nom d'utilisateur, mot de passe et chaîne de connexion) en utilisant les vôtres.


Ensuite en mode Menus Créés, il vous suffit de lancer le menu /Fichier/Démo... et suivre le dialogue. Le dialogue est un onglet qui décrit sur chacune des pages un objet qui a été présenté ici.


Voici un extrait de cette base pour l'objet package par exemple:

Pictures 0542x0380


Sur chaque page, on peut utiliser les boutons de connexion et de déconnexion à la base de données Oracle.

Pour obtenir la liste des objets pour un objet donné, il suffit de cliquer sur le bouton portant le nom de l'objet. Par exemple, sur l'illustration on a la liste des packages.

En cliquant sur un objet de la liste, on obtient les informations abordées pour cet objet dans cet article. Sur l'illustration, on obtient la liste des sous-programmes ainsi que leur type, et pour chaque sous-programme, la liste de ses paramètres et leurs types.


V. Conclusion

Cette note vous a montré l'utilisation de la commande 4D For OCI OCIDescribeAnyText, pour lire les informations descriptives des objets d'une base de données Oracle (Table, vue...), descriptions appelées aussi métadonnées. En partant de là, il vous est donc possible d'écrire une application cliente OCI générale qui décrirait l'ensemble de tous les objets d'une base Oracle, ce qui offre une visibilité plus grande sur la base de données.


VI. Base exemple

Téléchargez la base exemple :

base exemple

__________________________________________________
Copyright © 1985-2009 4D SA - Tous droits réservés
Tous les efforts ont été faits pour que le contenu de cette note technique présente le maximum de fiabilité possible.
Néanmoins, les différents éléments composant cette note technique, et le cas échéant, le code, sont fournis sans garantie d'aucune sorte. L'auteur et 4D S.A. déclinent donc toute responsabilité quant à l'utilisation qui pourrait être faite de ces éléments, tant à l'égard de leurs utilisateurs que des tiers.
Les informations contenues dans ce document peuvent faire l'objet de modifications sans préavis et ne sauraient en aucune manière engager 4D SA. La fourniture du logiciel décrit dans ce document est régie par un octroi de licence dont les termes sont précisés par ailleurs dans la licence électronique figurant sur le support du Logiciel et de la Documentation afférente. Le logiciel et sa documentation ne peuvent être utilisés, copiés ou reproduits sur quelque support que ce soit et de quelque manière que ce soit, que conformément aux termes de cette licence.
Aucune partie de ce document ne peut être reproduite ou recopiée de quelque manière que ce soit, électronique ou mécanique, y compris par photocopie, enregistrement, archivage ou tout autre procédé de stockage, de traitement et de récupération d'informations, pour d'autres buts que l'usage personnel de l'acheteur, et ce exclusivement aux conditions contractuelles, sans la permission explicite de 4D SA.
4D, 4D Calc, 4D Draw, 4D Write, 4D Insider, 4ème Dimension ®, 4D Server, 4D Compiler ainsi que les logos 4e Dimension, sont des marques enregistrées de 4D SA.
Windows,Windows NT,Win 32s et Microsoft sont des marques enregistrées de Microsoft Corporation.
Apple, Macintosh, Power Macintosh, LaserWriter, ImageWriter, QuickTime sont des marques enregistrées ou des noms commerciaux de Apple Computer,Inc.
Mac2Win Software Copyright © 1990-2002 est un produit de Altura Software,Inc.
4D Write contient des éléments de "MacLink Plus file translation", un produit de DataViz, Inc,55 Corporate drive,Trumbull,CT,USA.
XTND Copyright 1992-2002 © 4D SA. Tous droits réservés.
XTND Technology Copyright 1989-2002 © Claris Corporation.. Tous droits réservés ACROBAT © Copyright 1987-2002, Secret Commercial Adobe Systems Inc.Tous droits réservés. ACROBAT est une marque enregistrée d'Adobe Systems Inc.
Tous les autres noms de produits ou appellations sont des marques déposées ou des noms commerciaux appartenant à leurs propriétaires respectifs.
__________________________________________________
 



Valid XHTML 1.1!Valid CSS!

Ce document est issu de http://www.developpez.com et reste la propriété exclusive de son auteur. La copie, modification et/ou distribution par quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur.
Contacter le responsable de la rubrique 4D