Return variable from cx_Oracle PL/SQL call in Python

后端 未结 3 748
孤独总比滥情好
孤独总比滥情好 2020-12-19 06:29

I want to execute an Oracle PL/SQL statement via cx_oracle in Python. Code looks like this:

db = cx_Oracle.connect(user, pass, dsn_tns)
cursor = db.cursor()
         


        
3条回答
  •  再見小時候
    2020-12-19 07:32

    You need a function to return a result. An anonymous block will not.

    You need to create a function in the database, for instance:

    create or replace function calculation return number is
      c   number := 0.2;
      mn  number := 1.5;
      res number;
    begin
      return c + mn / 6.;
    end;
    /
    

    Then change your Python code to call the function, using, callfunc()

    db = cx_Oracle.connect(user, pass, dsn_tns)
    cursor = db.cursor()
    
    try:
      result = cursor.callfunc('calculation', float)
      print result
    except cx_Oracle.DatabaseError as e:
      err, = e.args
      print "\n".join([str(err.code),err.message,err.context])
    

    It's not possible to create a function on the fly but your function is simple enough that you can do it in a select statement and use fetchall() as described in the linked documentation to return the result to Python. fetchall() returns a list of tuples so if you're only after a single row and column you can immediately select the 0th index of both.

    >>> import cx_Oracle
    >>> db = cx_Oracle.connect('****','****','****')
    >>> cursor = db.cursor()
    >>> SQL = """select 0.2 + 1.5 / 6. from dual"""
    >>> try:
    ...     cursor.execute(SQL)
    ...     result = cursor.fetchall()[0][0]
    ... except cx_Oracle.DataBaseError, e:
    ...     pass
    ...
    <__builtin__.OracleCursor on >
    >>> result
    0.45000000000000001
    >>>
    

    You can also pass the variables into your execute() call using bind variables and therefore instantiate them in Python if necessary:

    >>> c = 0.2
    >>> mn = 1.5
    >>> SQL = """select :c + :mn / 6. from dual"""
    >>> bind_vars = { 'c' : c, 'mn' : mn }
    >>> cursor.execute(SQL, bind_vars)
    <__builtin__.OracleCursor on >
    >>> result = cursor.fetchall()[0][0]
    >>> result
    0.45000000000000001
    >>>
    

    Though it might be simpler to do all this in Python... I assume your actual situation is more complicated?

提交回复
热议问题