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

Interfaces de programmation Oracle Discussion :

[OCI] Récuperer le type d'une colonne


Sujet :

Interfaces de programmation Oracle

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé

    Profil pro
    Inscrit en
    Avril 2004
    Messages
    421
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2004
    Messages : 421
    Par défaut [OCI] Récuperer le type d'une colonne
    bonjour,

    voila, je dois d'utiliser la librairie OCI (et non OCIlib malheureusement) pour realiser une requete du type select * from table1.

    Tout ce passe bien jusqu'a ce que j'essaie de recuperer la premiere ligne.

    j'ai fait un OCIPrepare , suivi d'un OCI execute, jusque la tout va bien.

    le probleme c'est pour recuperer le resultat. Si j'ai bien compris (la doc etant pas tres clair la dessus), je recuperer d'abord le nombre de colonne que la reponse contient, suivi du type de chaque colonne puis je fais un OCIDefine, puis un fetch pour recuperer chaque ligne.

    la ou cela coince, c'est pour recuperer le type et faire l'appel du define.
    dans le define il faut faudra dire de quelle type sera la case. Soit SQLT_INT soit SQLT_STR;

    or quand je fait type == SQLT_INT ou type == SQLT_STR tout les deux sont faut.

    Comment savoir de quelle type sont les réponses?

    merci

    a++

  2. #2
    Rédacteur
    Avatar de Vincent Rogier
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    2 373
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 2 373
    Par défaut
    Et Pourquoi pas OCILIB ?

    Poste ton code ! Comment tu as recupéré le type ? Il faut savoir que OCI ne te fournira jamais SQLT_INT quand tu décris une colonne..

    Il te fournira dans 99 % cas SQLT_NUM pour la famille des number qui regoupre quasiment tous les numériques sauf les FLOAT (double, float, real, ..)

    En fait SQLT_INT est utilisé quant tu appelles OCIDefine().

    Résumons, tu as une colonnes de type sql INT (qui est en fait un NUMBER).

    Tu décris la colonne et tu obtiens SQL_NUM. SI tu veux récupérer la valeur sous forme de int en C , tu passes SQLT_INT pour définir la colonne et Oracle fera la conversion et mettra dans ton buffer des int...

    Bon, je ne suis peut être pas très clair (j'ai faim... faut aller bouffer..).

    Tu peux regarder le source d'OCILIB pour apprendre comment fonctionne OCI.

    N'hésites pas, je suis à ta disposition.
    Vincent Rogier.

    Rubrique ORACLE : Accueil - Forum - Tutoriels - FAQ - Livres - Blog

    Vous voulez contribuer à la rubrique Oracle ? Contactez la rubrique !

    OCILIB (C Driver for Oracle)

    Librairie C Open Source multi-plateformes pour accéder et manipuler des bases de données Oracle

  3. #3
    Membre éclairé

    Profil pro
    Inscrit en
    Avril 2004
    Messages
    421
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2004
    Messages : 421
    Par défaut
    bonjour et merci.

    Le truc c'est que j'ai pas le code ici (je l'ai oublié. je le mettrais demain matin)

    pourquoi pas ocilib, c'est assez compliquer mais en gros on peut pas (malheureusement). en fait, je dois faire une espece de portage dans un language totalement exotique etc... Peut etre par la suite pourquoi pas...mais c'est pas moi le patron

    merci pour tout en cas.

  4. #4
    Membre éclairé

    Profil pro
    Inscrit en
    Avril 2004
    Messages
    421
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2004
    Messages : 421
    Par défaut
    bonjour, voila quoi ressemble plus ou moins mon code (j'ai omis tout l'indispensable)


    j'essaie de recuperer la commande sqlsuivante

    'SELECT * FROM "table3"'

    pour cela

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    OCIStmtPrepare(	stmthp,errhp,(text *) Y_fmt,(ub4) Y_size,(ub4)OCI_NTV_SYNTAX,(ub4) OCI_DEFAULT);

    puis je l'execute

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    OCIStmtExecute(svchp, stmthp,  errhp,  (ub4) 0, (ub4) 0, (CONST OCISnapshot *) 0,  (OCISnapshot *) 0,(ub4) OCI_DEFAULT);
    puis je recupere le nombre de colonne que contient la reponse
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    OCIAttrGet((dvoid *)stmthp, OCI_HTYPE_STMT, (dvoid *)&Y_RESULT,(ub4 *)0, OCI_ATTR_PARAM_COUNT, errhp);
    puis pour chaque colonne, je recupere le type (que je sauvegarde)


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    Y_parmstatus = OCIParamGet((dvoid *)stmthp, OCI_HTYPE_STMT, errhp,(dvoid **)&mypard, (ub4) Y_number);
     
    OCIAttrGet(	(dvoid*) mypard, (ub4) OCI_DTYPE_PARAM, (dvoid*) &Y_dtype,(ub4 *) 0, (ub4) OCI_ATTR_DATA_TYPE,(OCIError *) errhp  );
    et puis enfin, je fait un define (avant de faire un fetch)
    et c'est la que j'ai un probleme car je dois savoir le type

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    IF type[i] == SQLT_INT  THEN
    OCIDefineByPos(	stmthp,&defnp,errhp,Y_col,(dvoid *)SQL_INT,(sb4) 1024,SQLT_INT,NULL,NULL,NULL,OCI_DEFAULT);
    ELSE iF type[i] == SQLT_STR
    OCIDefineByPos(	stmthp,&defnp,errhp,Y_col,(dvoid *)SQL_STR,(sb4) 1024,SQLT_INT,NULL,NULL,NULL,OCI_DEFAULT);
    END;
    J'ai essayer STR_NUM, et ca fonctione pour ce qui est nombre mais pas pour ce qui SQL_STR en fait, les codes (si je fait un print du type) sont 2 et 112.
    ce qui fait que c'est un SQLT_CLOB or normalement cela doit etre un char...
    bizarre, en plus,cela me vaut une belle erreur

    Fetch - ORA-00932: inconsistent datatypes: expected NUMBER got DTY0
    mis bon, ca c'est pas pour tout de suite.

    salutation et merci pour tout.

    a++

  5. #5
    Rédacteur
    Avatar de Vincent Rogier
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    2 373
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 2 373
    Par défaut
    Déja tu pourrais aussi poster le DDL de la table

    De même que Oracle ne renverra jamais SQLT_INT pour un number même entier (car SQLT_INT ne sert que dans l'autre sens, c'est à dire pour lui inqiuer que son number, tu veux le récuperer dans un int), SQLT_STR ne te sera jamais renvoyé par ORACLE... C'est en général un type que tu fournit à OCIDefine() pour qu'il te renvoi le buffer (char, varchar, ...) sous forme de chaines C à zéro terminal.

    Donc, pour résumer :
    • certains SQLT_XXX sont utilisés par Oracle comme retour de OCIParamGet() avec OCI_ATTR_DATA_TYPE
    • les autres sont pour toi afin de dire à ORacle comment tu veux qu'il te retourne buffer lors de l'appel à OCIDefine()
    Par exemple, voici le code extrait d'OCIB qui sert à mapper les champs (tous les types Oracle tirés de ocidfn.h sont traités dans le switch):

    col->ocode est le code SQLT_XXX récupéré d'Oracle
    col->icode est le code SQLT_XXX qui sera fournit à OCIDefine()

    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
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
     
     
        /* .... */
     
        col->icode = col->ocode;
     
        /* ... */
     
        switch (col->icode)
        {
            case SQLT_INT:
            case SQLT_UIN:
     
                col->type    = OCI_CDT_INTEGER;
                col->bufsize = sizeof(int);
                break;
     
            case SQLT_FLT:
            case SQLT_BFLOAT:
            case SQLT_BDOUBLE:
            case SQLT_IBFLOAT:
            case SQLT_IBDOUBLE:
     
                col->type    = OCI_CDT_DOUBLE;
                col->bufsize = sizeof(double);
                break;
     
            case SQLT_VNU:
            case SQLT_PDN:
            case SQLT_NUM:
     
                /* OCILIB tries to map few NUMBER based columns (INT, INTEGER, ...)
                   to C int types intead of double for perfomance.
                   So, it tries to detect decimal columns from columns atributes */
     
                if (col->scale == 0 && col->prec != 0 && col->prec <= 38)
                {
                    col->icode   = SQLT_INT;
                    col->type    = OCI_CDT_INTEGER;
                    col->bufsize = sizeof(int);
                }
                else
                {
                    col->icode   = SQLT_FLT;
                    col->type    = OCI_CDT_DOUBLE;
                    col->bufsize = sizeof(double);
                }
     
                break;
     
            case SQLT_DAT:
            case SQLT_ODT:
     
                col->icode   = SQLT_ODT;
                col->type    = OCI_CDT_DATETIME;
                col->bufsize = sizeof(OCIDate);
                break;
     
            case SQLT_CUR:
            case SQLT_RSET:
     
                col->type     = OCI_CDT_CURSOR;
                col->bufsize  = sizeof(OCIStmt *);
                col->dtype    = OCI_HTYPE_STMT;
                break;
     
            case SQLT_RDD:
            case SQLT_RID:
     
                col->icode   = SQLT_STR;
                col->type    = OCI_CDT_TEXT;
                col->bufsize = (OCI_SIZE_ROWID+1) * sizeof(dtext);
                break;
     
            case SQLT_BIN:
     
                col->type    = OCI_CDT_RAW;
                col->bufsize = col->size;
                break;
     
            case SQLT_BLOB:
     
                col->type    = OCI_CDT_LOB;
                col->subtype = OCI_BLOB;
                col->dtype   = OCI_DTYPE_LOB;
                col->bufsize = sizeof(OCILobLocator *);
                break;
     
            case SQLT_CLOB:
     
                col->type    = OCI_CDT_LOB;
                col->dtype   = OCI_DTYPE_LOB;
                col->bufsize = sizeof(OCILobLocator *);
     
                if (col->csfrm == SQLCS_NCHAR)
                    col->subtype = OCI_NCLOB;
                else
                    col->subtype = OCI_CLOB;
     
                break;
     
            case SQLT_BFILE:
     
                col->type    = OCI_CDT_FILE;
                col->subtype = OCI_BFILE;
                col->dtype   = OCI_DTYPE_LOB;
                col->bufsize = sizeof(OCILobLocator *);
                break;
     
            case SQLT_CFILE:
     
                col->type    = OCI_CDT_FILE;
                col->subtype = OCI_CFILE;
                col->bufsize = sizeof(OCILobLocator *);
                col->dtype   = OCI_DTYPE_LOB;
                break;
     
            case SQLT_LNG:
            case SQLT_LVC:
            case SQLT_LBI:
            case SQLT_LVB:
            case SQLT_VBI:
     
                if ((col->icode == SQLT_LNG || col->icode == SQLT_LVC) &&
                    (stmt != NULL && stmt->long_mode == OCI_LONG_IMPLICIT))
                {
                     col->type = OCI_CDT_TEXT;
                     col->bufsize = (OCI_SIZE_LONG+1);
                }
                else
                {
                    if (stmt != NULL)
                    {
                        stmt->fetch_mode = OCI_DYNAMIC_FETCH;
                        stmt->piecewise  = TRUE;
                    }
     
                    col->type    = OCI_CDT_LONG;
                    col->bufsize = INT_MAX;
     
                    if (col->icode == SQLT_LBI ||
                        col->icode == SQLT_LVB ||
                        col->icode == SQLT_VBI)
                    {
                        col->subtype = OCI_BLONG;
                    }
                    else
                    {
                        col->subtype = OCI_CLONG;
                    }
     
                }
     
                break;
     
    #if OCI_VERSION_COMPILE >= OCI_9
     
            case SQLT_TIMESTAMP:
     
                col->type    = OCI_CDT_TIMESTAMP;
                col->subtype = OCI_TIMESTAMP;
                col->dtype   = OCI_DTYPE_TIMESTAMP;
                col->bufsize = sizeof(OCIDateTime *);
                break;
     
            case SQLT_TIMESTAMP_TZ:
     
                col->type    = OCI_CDT_TIMESTAMP;
                col->subtype = OCI_TIMESTAMP_TZ;
                col->dtype   = OCI_DTYPE_TIMESTAMP_TZ;
                col->bufsize = sizeof(OCIDateTime *);
                break;
     
            case SQLT_TIMESTAMP_LTZ:
     
                col->type    = OCI_CDT_TIMESTAMP;
                col->subtype = OCI_TIMESTAMP_LTZ;
                col->dtype   = OCI_DTYPE_TIMESTAMP_LTZ;
                col->bufsize = sizeof(OCIDateTime *);
                break;
     
            case SQLT_INTERVAL_YM:
     
                col->type    = OCI_CDT_INTERVAL;
                col->subtype = OCI_INTERVAL_YM;
                col->dtype   = OCI_DTYPE_INTERVAL_YM;
                col->bufsize = sizeof(OCIInterval *);
                break;
     
            case SQLT_INTERVAL_DS:
     
                col->type    = OCI_CDT_INTERVAL;
                col->subtype = OCI_INTERVAL_DS;
                col->dtype   = OCI_DTYPE_INTERVAL_DS;
                col->bufsize = sizeof(OCIInterval *);
                break;
     
    #endif
            case SQLT_NTY:
            case SQLT_PNTY:
            {
                col->icode   = SQLT_NTY;
                col->type    = OCI_CDT_OBJECT;                    
                col->bufsize = sizeof(void *);
                break;
            }
            case SQLT_REF:
     
                /* not supported datatypes */
     
                OCI_ErrorDatatypes(col->icode);
                return FALSE;
     
            case SQLT_CHR:
            case SQLT_STR:
            case SQLT_VCS:
            case SQLT_AFC:
            case SQLT_AVC:
            case SQLT_VST:
            case SQLT_LAB:
            case SQLT_OSL:
            case SQLT_SLS:
            default:
     
                col->icode   = SQLT_STR;
                col->type    = OCI_CDT_TEXT;
                col->bufsize = (col->size + 1) * sizeof(dtext);
                break;
        }
     
        return TRUE
     
        /* .... */
    Vincent Rogier.

    Rubrique ORACLE : Accueil - Forum - Tutoriels - FAQ - Livres - Blog

    Vous voulez contribuer à la rubrique Oracle ? Contactez la rubrique !

    OCILIB (C Driver for Oracle)

    Librairie C Open Source multi-plateformes pour accéder et manipuler des bases de données Oracle

  6. #6
    Membre éclairé

    Profil pro
    Inscrit en
    Avril 2004
    Messages
    421
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2004
    Messages : 421
    Par défaut
    wouahh... merci pour tout.
    je regarderais cela demain a mon aise.


    a++ et encore merci

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

Discussions similaires

  1. Réponses: 10
    Dernier message: 02/02/2007, 00h02
  2. [C#]Modifier le type d'une colonne dans un datatable
    Par Mahoret dans le forum Windows Forms
    Réponses: 2
    Dernier message: 26/09/2006, 09h03
  3. [C#][Débutant] Comment récuperer la valeur d'une colonne d'une grille
    Par Cazaux-Moutou-Philippe dans le forum Windows Forms
    Réponses: 2
    Dernier message: 30/04/2006, 05h40
  4. Changer le type d'une colonne
    Par Poisson59 dans le forum Oracle
    Réponses: 2
    Dernier message: 06/12/2005, 13h59
  5. [Débutant] Changer le type d'une colonne
    Par david71 dans le forum MS SQL Server
    Réponses: 8
    Dernier message: 08/11/2005, 11h26

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