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

Python Discussion :

pb d'interface avec une procédure Oracle stockée


Sujet :

Python

  1. #1
    Membre éprouvé Avatar de awalter1
    Inscrit en
    Août 2004
    Messages
    994
    Détails du profil
    Informations forums :
    Inscription : Août 2004
    Messages : 994
    Par défaut pb d'interface avec une procédure Oracle stockée
    Bonjour,
    J'ai un petit souci qui demande des connaissances de python, de cx_oracle(pour interfacer oracle) et de PL/SQL.
    J'ai des procédures stockées Oracle que j'interface avec cx_Oracle. Jusque là je n'avais pas de pb, ça marchait bien ! A présent je dois utiliser une procédure stockée qui renvoie un tableau de valeurs : cette procédure stockée est utilisée par du C et elle marche bien. Mais avec Python je ne sais pas quel type va récupérer ce tableau de valeurs.
    Voici l'appel de ma procédure stockée :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    listret = []
    self.I_database.callproc("copy.CopyGetWorldAirportInRect",["XXX",listret])
    listret doit récupérer le tableau de valeurs : je pensais le récupérer dans une liste, mais ça le fait pas.
    Et l'interfaçage de cx_Oracle :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    def callproc(self, proc, arg):
         try:
            	self.cursor.callproc(proc, arg)
         except cx_Oracle.DatabaseError, oerr:
    		raise cx_Oracle.DatabaseError, ['', "%s"%(oerr.args[0])]
    Et enfin un extrait de la procédure 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
    PROCEDURE CopyGetWorldAirportInRect(this_airspace_name IN VARCHAR2,listret OUT TabTypAirportCode) IS
    	CURSOR CurWairport IS
    	SELECT AIRPORT_CODE,DEG_LATITUDE,MIN_LATITUDE,HEMISPHERE,SEC_LATITUDE,DEG_LONGITUDE,MIN_LONGITUDE,DIRECTION,SEC_LONGITUDE,FULL_NAME 
    	FROM w_airpor;
    	pos BINARY_INTEGER := 0;
    BEGIN
    	FOR cur IN CurWairport LOOP
     		pos := pos + 1;
    		listret(pos) := cur.AIRPORT_CODE;
            	EXIT WHEN CurWairport%NOTFOUND;
    	END LOOP;
     
    END CopyGetWorldAirportInRect;
    Le pb se situe sur le paramètre en sortie : listret car si je remplace son type par un varchar2 et que je me limite à retourner une seule valeur, ça marche bien. L'erreur signalée est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Message = proc = copy.CopyGetWorldAirportInRect, errmsg = ['', "ORA-06550: line 1, column 13:\nPLS-00222: no function with name 'COPYGETWORLDAIRPORTINRECT' exists in this scope\nORA-06550: line 1, column 7:\nPL/SQL: Statement ignored\n"]
    Merci

  2. #2
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 718
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 718
    Par défaut
    Salut,

    D'après ce tuto, il faut passer l'équivalent d'un cursor:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     def find_employees(self, p_query):
        # as it comes to all complex types we need to tell Oracle Client
        # what type to expect from an OUT parameter
        l_cur = self.__cursor.var(cx_Oracle.CURSOR)
        l_query, l_emp = self.__cursor.callproc("PKG_HR.FIND_EMPLOYEES", [p_query, l_cur]) 
        return list(l_emp)
    Et aligner la PS ainsi:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    PROCEDURE find_employees(
        p_query IN VARCHAR2,
        p_results OUT SYS_REFCURSOR
      ) AS
      BEGIN
        OPEN p_results FOR
          SELECT *
          FROM employees
          WHERE UPPER(first_name||' '||last_name||' '||email) LIKE '%'||UPPER(p_query)||'%';
      END find_employees;
    Mais pas d'Oracle sous la main pour voir si çà fonctionne.
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  3. #3
    Membre éprouvé Avatar de awalter1
    Inscrit en
    Août 2004
    Messages
    994
    Détails du profil
    Informations forums :
    Inscription : Août 2004
    Messages : 994
    Par défaut
    c'est fort si ça marche, en tout cas ça ne s'invente pas. J'essaye dés Lundi.
    Merci

  4. #4
    Membre éprouvé Avatar de awalter1
    Inscrit en
    Août 2004
    Messages
    994
    Détails du profil
    Informations forums :
    Inscription : Août 2004
    Messages : 994
    Par défaut
    Après test, la solution marche tel que. Cependant, cela ne marche qu'avec un seul paramètre (le p_query). SI je mets deux paramètres je sors en erreur :
    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
    PROCEDURE CopyGetWorldAirportInRect(ullati IN NUMBER,ullatj IN NUMBER,listret OUT SYS_REFCURSOR) AS 
    BEGIN
    	OPEN listret FOR
    	SELECT AIRPORT_CODE,DEG_LATITUDE,MIN_LATITUDE,HEMISPHERE,SEC_LATITUDE,DEG_LONGITUDE,MIN_LONGITUDE,DIRECTION,SEC_LONGITUDE,FULL_NAME 
    	FROM w_airpor;
     
    END CopyGetWorldAirportInRect;
     
    et coté python, le fichier toto.py :
     
    import cx_Oracle
     
    class HR:
      def __init__(self):
        self.__db = cx_Oracle.Connection("ACE2011B/ipas0@ALLSIMUL")
        self.__cursor = self.__db.cursor()
     
      def __exit__(self, type, value, traceback):
        self.__cursor.close()
        self.__db.close()
     
      def find_employees(self):
        # as it comes to all complex types we need to tell Oracle Client
        # what type to expect from an OUT parameter
        l_cur = self.__cursor.var(cx_Oracle.CURSOR)
        l_query, l_emp = self.__cursor.callproc("copy.CopyGetWorldAirportInRect", [-35,-1,l_cur]) 
     
        return list(l_emp)
     
    if __name__ == '__main__':
     
    	db1 = HR() 
    	l = db1.find_employees()
        	print "find_employees : ",l
    L'erreur générée est la suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Traceback (most recent call last):
      File "toto.py", line 22, in <module>
        l = db1.find_employees()
      File "toto.py", line 16, in find_employees
        l_query, l_emp = self.__cursor.callproc("copy.CopyGetWorldAirportInRect", [-35,-1,l_cur])
    ValueError: too many values to unpack
    C'est étrange cette restriction !

  5. #5
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 060
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 060
    Par défaut
    Affiche le résultat de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    self.__cursor.callproc("copy.CopyGetWorldAirportInRect", [-35,-1,l_cur])
    Tu comprendras je pense...

  6. #6
    Membre éprouvé Avatar de awalter1
    Inscrit en
    Août 2004
    Messages
    994
    Détails du profil
    Informations forums :
    Inscription : Août 2004
    Messages : 994
    Par défaut
    Oui j'ai compris
    Merci du coup de main

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

Discussions similaires

  1. [SS2K5] : Peupler une CTE avec une procédure stockée
    Par jeff37 dans le forum MS SQL Server
    Réponses: 1
    Dernier message: 24/03/2007, 10h25
  2. [PEAR][MDB2] Erreur avec une procédure stockée
    Par mikedavem dans le forum Bibliothèques et frameworks
    Réponses: 4
    Dernier message: 04/01/2007, 16h49
  3. Réponses: 2
    Dernier message: 06/12/2006, 08h54
  4. [format des données avec une procédure stockée]
    Par viny dans le forum PostgreSQL
    Réponses: 7
    Dernier message: 10/03/2005, 13h24
  5. Problème avec une procédure stockée
    Par in dans le forum Langage SQL
    Réponses: 4
    Dernier message: 27/05/2003, 15h33

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