问题
Is it possible to call Python within an Oracle procedure? I've read plenty of literature about the reverse case (calling Oracle SQL from Python), but not the other way around.
What I would like to do is to have Oracle produce a database table, then I would like to call Python and pass this database table to it in a DataFrame so that I could use Python to do something to it and produce results. I might need to call Python several times during the Oracle procedure. Does anyone know if this is possible and how could it be done?
回答1:
You can write stored procedures in Java and you can use Java to run Python code, so you can possibly combine the two to achieve what you want.
回答2:
On the edge there is a possibility on how to overcome the PL/SQL limitations. You can design a specific interface between Database and Python program. I suppose You'd use one of the Python's library to get some data from the Net. And then exchange it's data with Oracle using the C Library.
call python using c library -> data file -> external table -> data
NOTICE: Take it as a proof of concept or rather starting point for deeper exploration. Also I'd strongly discourage You from using it on production. Breaking the PL/SQL jail to call system program could be considered at least as unsafe.
So this is the possible way on how to proceed:
--== Prerequisities ==--
pip install quandl
--== quandl.py ==--
#!/usr/bin/python
import quandl
# World Bank Education Statistics
# Population, tertiary, total - Czech Republic
data = quandl.get("WEDU/CZE_SP_TER_TOTL_IN")
data.to_csv("/u01/data/data.txt")
--== exec.c ==--
//
// gcc -Wall -fPIC -c exec.c
// gcc -shared -o exec.so exec.o
// mkdir -p /u01/lib
// cp exec.so /u01/lib
//
#include <stdlib.h>
int execute() {
system("/u01/bin/get_data.py");
return 0; // We want to make the compiler happy
}
--== LISTENER CONFIGURATION ==--
SID_LIST_LISTENER =
...
(SID_DESC =
...
(ENVS="EXTPROC_DLLS=ANY")
(PROGRAM = extproc)
...
--== DDL PART ==--
create or replace library c_exec is '/u01/lib/exec.so';
create or replace procedure exec as external
name "execute"
library c_exec
language c;
/
create directory pydata as '/u01/data';
create table data (
"date" varchar2(14),
"value" varchar2(32)
) organization external (
type oracle_loader
default directory pydata
access parameters (
records delimited by newline
nobadfile nodiscardfile nologfile
fields terminated by ','
) location (pydata:'data.txt')
);
---=== USAGE ===---
--== DOWNLOAD DATA FOR PROCESSING ==--
Using the external PL/SQL C library You would call the python program that stores the result to the expected location for the external table.
execute exec;
--== QUERY THE DATA ==--
select
to_date("date",'yyyy-mm-dd') "date",
to_number("value") "value"
from data
where "date" != 'Date';
--== RESULT ==--
date value
--------- ----------
31-DEC-70 886414
31-DEC-71 885549
31-DEC-72 877533
31-DEC-73 862859
回答3:
I guess this is directly impossible because PL/SQL is specially designed for fast execution inside Oracle server and this isn't place where arbitrary code of other vendor is possible, due to internal limitations.
OTOH you can interact with another server from a stored procedure via TCP channels, this page refers UTL_TCP package. In an external network server, you can utilize any language and any logic.
回答4:
You can use the Preprocessor feature with external tables, which allows you to invoke a Python script to populate an external table with data. An example can be found in the Using External Table section of this OTN article: https://community.oracle.com/docs/DOC-994731.
回答5:
kind of complicated but possible. I have seen it once. You need to
- create a javaclass inside oracle database. This class calls a .py file in the directory which contains it.
- create a procedure that calls the java class of item 1.
- in your sql query, call the procedure of item 2 whenever you need it.
来源:https://stackoverflow.com/questions/22564503/calling-python-from-oracle