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

C# Discussion :

[.NET Oracle] Passage d'un tableau en paramètre d'une requête


Sujet :

C#

  1. #1
    Membre habitué Avatar de NeraOne
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2007
    Messages
    218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2007
    Messages : 218
    Points : 128
    Points
    128
    Par défaut [.NET Oracle] Passage d'un tableau en paramètre d'une requête
    Salut les loulous !

    Je travaille sur .NET en C# et je développe une bibliothèque géométrique basée sur NetTopologySuite. Je récupère et je sauvegarde mes géométries sur une base Oracle Spatial (Oracle 10g).
    Je rencontre un soucis qui peut très vite être bloquant pour mon appli. Je sais pas si vous connaissait la structure d'un objet Oracle Spatial : SDO_GEOMETRY, mais bon à la limite c'est pas grave... Si j'ai un polygone défini par 10 000 points par exemple (chose qui n'est pas rare du tout), je peux pas caler mes 10 000 points directement dans la requête par une concaténantion, car Oracle me jette en me disant : Too many arguments. Par sécurité, j'ai vérifier la taille des tableaux de points que supporte Oracle : 1 048 576 occurences... donc c'est pas ça qui gène. Je pense qu'au dela d'un certains nombre de caractères, Oracle n'accepte plus la requête, je ne sais pour quelle raison !
    Ce que je voudrais faire : au lieu de passer toute la chaîne de points directement, passer en paramètre un tableau de points pour pas que le Text de la requête explose et pour que je puisse passer autant de points que je veux !
    Je n'ai absolument aucune idée de comment je pourrai faire cela... MaiS : je sais que ça existe, enfin je connaîs l'homme qui a vu l'homme qui a vu l'homme qui a vu l'ours le faire
    Si certains pouvez m'eclairer la dessus, ce serait cool ! Merci beaucoup et @+
    Antoine

  2. #2
    Membre habitué Avatar de NeraOne
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2007
    Messages
    218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2007
    Messages : 218
    Points : 128
    Points
    128
    Par défaut
    Je précise également que, pour des raisons de performence, j'utilise le "driver" fait par Oracle : Oracle.DataAccess et non pas celui de Microsoft : System.Data.OracleClient.
    J'ai regardé du côté de la classe OracleParameterCollection mais je n'arrive pas du tout à la faire fonctionner... J'ai créer un tableau de OracleParameter mais bon, il n'empêche qu'au final je suis obligé de lister dans la requête le nom de chaque paramètres, je peux en mettre plus car je met des nom cours mais bon, ce n'est que repousser le problème...

    Pas d'idée ?¿

  3. #3
    Membre habitué Avatar de NeraOne
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2007
    Messages
    218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2007
    Messages : 218
    Points : 128
    Points
    128
    Par défaut
    Ralalala je suis blazé, je suis parti vendredi en me disant que j'aurai une réponse lundi matin puis rien... Personne n'a jamais réussi à passer un tableau en paramètre à une requête Oracle ???????????????? Please Help Me

    @++
    Antoine

  4. #4
    Membre régulier
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    109
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Décembre 2004
    Messages : 109
    Points : 120
    Points
    120
    Par défaut
    Sisi tu peux passer des tableaux, mais tu ne peux pas utiliser n'importe quelle collection oracle.
    Regarde l'exemple sur le site du driver odp.net. Par exemple :

    Using PL/SQL Associative Arrays
    http://www.oracle.com/technology/ora...an/o17odp.html

  5. #5
    Membre habitué Avatar de NeraOne
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2007
    Messages
    218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2007
    Messages : 218
    Points : 128
    Points
    128
    Par défaut Re
    Merci de ta réponse karlus mais je ne préfére pas faire cela en PL/SQL ni avec des procédures stockées d'abord parce que je ne maîtrise pas du tout cela et ensuite parce que c'est assez lourd (on m'a dit que...) !
    Je voudrais vraiment, si cela existe, queuq'choz d'pluusssss béïzik (spécial dédicace au têtes à claques ).
    Pour passer un paramètre, on fait cela :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    OracleConnection conn = new OracleConnection(); //Connexion
    OracleCommand requete = new OracleCommand(); //Requête
    OracleParameter param = requete.Parameters.Add(new OracleParameter(":param", OracleDbType.Double)); //Paramètre
    requete.CommandText = ("select * from TEST where cle = :param"); //Texte de la requête
    param.Value = 51;
    //Et après on exécute !
    Moi je voudrais un truc du même genre en fait mais sauf que le param ce serai un tableau :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    OracleConnection conn = new OracleConnection(); //Connexion
    OracleCommand requete = new OracleCommand(); //Requête
    OracleParameter param = requete.Parameters.Add(new OracleParameter(":param", OracleDbType.???)); //Paramètre de type tableau
    requete.CommandText = ("select * from TEST where cle = :param"); //Texte de la requête
    param.Value = monTableau; //monTableau que je définis avant...
    //Et après on exécute !
    Ca existe ça avec Oracle 10G sans passé par des procédures stockées, aussi simple que ça ?????
    Merci d'avance !
    ++
    Antoine

  6. #6
    Membre régulier
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    109
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Décembre 2004
    Messages : 109
    Points : 120
    Points
    120
    Par défaut
    A ma connaissance non. Mais pour ma part une requête avec une clause where ... in ( , , , ) avec 10000 paramètres j'essaierai de l'éviter.
    Tu devrais peut être quand même jeter un oeil sur les collections PL/SQL. Ca pourrait peut être t'éviter ce type de requête et puis c'est pas si lourd que ça

  7. #7
    Membre habitué Avatar de NeraOne
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2007
    Messages
    218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2007
    Messages : 218
    Points : 128
    Points
    128
    Par défaut
    Oui alors je me corrige de suite, j'ai mis un select pour faire simple mais je suis trompé, c'est pas utilisé de cette façon.
    C'est pour faire une insertion ou un update sur des type SDO_GEOMETRY (oracle spatial). Ce que je faisais à la base c'était des requêtes du type :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    "INSERT INTO maTable (CLE, GEOM), VALUES (1, sdo_geometry(2002, 41014, null, sdo_elem_info_array(1, 2, 1), sdo_ordinate_array(0, 0, 1, 1, 2, 2, 3, 3,.........)))"
    0, 0, 1, 1, 2, 2, 3, 3,......... = la liste des points
    Ca, ça pète très vite dès qu'on a un peu trop de points !!!
    Donc ce que je veux faire c'est pareil mais passer un tableau au lieu de ma liste de points du style :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    "INSERT INTO maTable (CLE, GEOM), VALUES (1, sdo_geometry(2002, 41014, null, sdo_elem_info_array(1, 2, 1), sdo_ordinate_array(:monTableau)))"
    Donc du coup je peux pas éviter ce genre de requête super lourde !
    Je vais donc regarder du côté de ce dont tu me parles karlus !!!
    @++
    Antoine

  8. #8
    Membre régulier
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    109
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Décembre 2004
    Messages : 109
    Points : 120
    Points
    120
    Par défaut
    OK. J'ai juste jeté un oeil par curiosité et il semble qu'en utilisant une "bind variable" certains s'en sont sortis ( au moins en java mais ça ne semble pas fonctionner dans ton cas )
    http://forums.oracle.com/forums/thre...hreadID=176606

    Tu peux tenter de passer directement un tableau à une procédure PL/SQL qui fera le boulot. Il y a un exemple de procédure PL/SQL qui instancie un VARRAY :

    http://forums.oracle.com/forums/thre...361450&#361450

    Néanmoins comme le type sdo_ordinate_array est un VARRAY tu ne pourras peut être pas appeler ce type directement depuis odp.net. Par contre aucun problème pour passer ton tableau .Net sous forme d'Associative Array comme indiqué dans la doc plus haut et ensuite peut être faire faire le boulot en PL/SQL pour passer du type Associative array au type VARRAY ( et donc sdo_ordinate_array ).

    j'espère que ça te sera utile et bon courage

  9. #9
    Membre habitué Avatar de NeraOne
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2007
    Messages
    218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2007
    Messages : 218
    Points : 128
    Points
    128
    Par défaut
    Super ton petit lien pour la procédure PL/SQL, du coup j'ai écrit une petite fonction dans un package pour pouvoir l'appeler quand je veux ! Mais j'ai un soucis, je sais pas du tout comment l'appeler en C#, et en lui filant correctement les paramètres... La fonction donne cela, je sais pas du tout si c'est bon, j'ai fait de l'ADA mais jamais du PL/SQL :
    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
    //En PL/SQL les commentaires débute par --, j'ai mis // uniquement pour la coloration
    PACKAGE BODY "MABASE"."PACKAGE1" IS
     
       FUNCTION "INSERTIONGEOM" ("CLE" IN INT, "TYPEGEOM" IN INT, "SPATIALREF" IN INT, "ELEM_INFO_ARRAY" IN TABLE_NUM, "ORDINATE_ARRAY" IN TABLE_NUM) RETURN NUMBER IS
     
          //Déclaration des variables
          elem MDSYS.SDO_ELEM_INFO_ARRAY;
          ord MDSYS.SDO_ORDINATE_ARRAY;
          srid INT;
          gtype INT;
          i INT;
     
          BEGIN
             //Instanciation des variables en fonction des paramètres
             gtype := TYPEGEOM;
             srid := SPATIALREF;
             elem := MDSYS.SDO_ELEM_INFO_ARRAY();
             ord := MDSYS.SDO_ORDINATE_ARRAY();
     
             //Définition de la taille des tableau (même taille que les paramètres)
             elem.EXTEND("ELEM_INFO_ARRAY".COUNT);
             ord.EXTEND("ORDINATE_ARRAY".COUNT);
     
             //Boucle pour elem info
             for i in 1 .. ELEM_INFO_ARRAY.COUNT LOOP
                elem(i) := ELEM_INFO_ARRAY(i);
             END LOOP;
     
             //Boucle pour ordinate
             for i in 1 .. ORDINATE_ARRAY.COUNT LOOP
                ord(i) := ORDINATE_ARRAY(i);
             END LOOP;
     
             //Requête
             INSERT INTO TESTGEOM (CLEGEOM, GEOM)
             VALUES (CLE, MDSYS.SDO_GEOMETRY(gtype, srid, NULL,elem, ord));
     
       END "INSERTIONGEOM";
    END "PACKAGE1";
    Après je vais essayer de trouver comment appeler correctement cette fonction en C# mais bon si tu sais karlus, ou si d'autre savent, ça "m'efficasera" le dev
    En tout cas, merci beaucoup de ton intérêt !
    @++
    Antoine

  10. #10
    Membre régulier
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    109
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Décembre 2004
    Messages : 109
    Points : 120
    Points
    120
    Par défaut
    c'est quoi ton type TABLE_NUM ? un Associative Array que tu as déclaré dans ton package ? ton package est bien compilé ( tu devrais avoir un END PACKAGE1 non ? )

    Sinon en gros :
    déclare ton type associative array dans l'en-tête d'un package :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    create or replace PACKAGE PACKAGE1
    AS
    TYPE TABLE_NUM IS TABLE OF NUMBER (8) INDEX BY BINARY_INTEGER
    END PACKAGE1;
    ensuite ton corps de package dans lequel tu manipules ton associative array pour faire ton insert

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    create or replace PACKAGE BODY PACKAGE1
    AS
    FUNCTION INSERTIONGEOM ........
     
    ...
     
    END INSERTIONGEOM;
    END PACKAGE1;
    L'appel depuis C# via odp.net s'effectue comme indiqué dans le lien que je t'ai donné plus haut ( Using PL/SQL Associative Arrays ). Quelque chose du genre

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    OracleCommand cmd = con.CreateCommand();
    cmd.CommandText = "PACKAGE1.INSERTIONGEOM";
    cmd.CommandType = CommandType.StoredProcedure;
     
    //...
     
    // ton paramètre array
    OracleParameter p_job_id = new OracleParameter();
    p_job_id.OracleDbType = OracleDbType.Int32;
    p_job_id.CollectionType = OracleCollectionType.PLSQLAssociativeArray;
    p_job_id.Value = new int[3] { 12, 2, 2 };
    p_job_id.Size = 3;

  11. #11
    Membre habitué Avatar de NeraOne
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2007
    Messages
    218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2007
    Messages : 218
    Points : 128
    Points
    128
    Par défaut
    Le package est bien fermé, je me suis gourer en voulant modifier pour le post... Mon type TABLE_NUM est comme cela :
    TYPE TABLE_NUM is TABLE of DOUBLE PRECISION;
    Je sais pas si c'est bon, je vais aussi essyayer avec ce que tu m'a filer mais il faut des doubles, je vais voir ça !
    Ok pour l'appel, je test ça ! Désolé je suis un peu à la masse en ce moment, j'ai du mal a compiler l'ensemble des informations que tu m'as donné pour m'en demerder
    Je test tout ça et je te tiens au courant ! (aujourd'hui je sais pas mais sur demain !) Mais comme y'a plusieurs paramètres dans ma fonctions PL/SQL, je dois pas les référencer dans le cmd.CommandText, ou c'est juste suivant l'ordre de déclaration qui seront mis au bon endroit ???
    ++ et encore merci !
    Antoine

  12. #12
    Membre habitué Avatar de NeraOne
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2007
    Messages
    218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2007
    Messages : 218
    Points : 128
    Points
    128
    Par défaut Merci
    Bon bah karlus, merci 1000 fois pour ton aide, j'ai réussi pile poil a faire ce que je voulais ! J'arrive donc a enregistrer, via une procédure stockée, n'importe quelle géométrie quelque soit sa taille !
    Si certains sont interessés pour avoir le code, n'hésitez surtout pas !

    Merci encore karlus et @ la prochaine
    ++
    Antoine

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

Discussions similaires

  1. Réponses: 6
    Dernier message: 27/09/2007, 13h38
  2. Réponses: 6
    Dernier message: 24/07/2006, 15h22
  3. Procédure stockée : passage d'un tableau en paramètres
    Par thomas_strass dans le forum MS SQL Server
    Réponses: 6
    Dernier message: 12/05/2006, 14h52
  4. [JpGraph] Passage d'un tableau en paramètre dans une URL pour JPgraph
    Par crazydiver_e2 dans le forum Bibliothèques et frameworks
    Réponses: 4
    Dernier message: 16/01/2006, 16h15
  5. Réponses: 7
    Dernier message: 18/05/2005, 15h09

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