使用 callproc 从 django 调用 PL/SQL 过程

Posted

技术标签:

【中文标题】使用 callproc 从 django 调用 PL/SQL 过程【英文标题】:Calling a PL/SQL procedure from django with callproc 【发布时间】:2019-07-25 15:06:55 【问题描述】:

我需要从 Django 中的 API 调用 PL/SQL 中的过程。我使用 callproc 和正确的值,但得到错误:

“PLS-00306:调用中的参数数量或类型错误”

在甲骨文我有:

PROCEDURE new_payment(pv_id                     IN VARCHAR2,
                        parr_user               IN OWA.vc_arr,
                        parr_date_reg           IN OWA.vc_arr,
                        parr_d_value            IN OWA.vc_arr,
                        parr_descr              IN OWA.vc_arr,
                        parr_type               IN OWA.vc_arr,
                        pi_gerar_ref_mb         IN PLS_INTEGER DEFAULT 0,
                        pv_data_limite_ref_mb   IN VARCHAR2 DEFAULT NULL)

在 models.py 我有:

class PAYMENT():
    def new_payment(self, id, user, date_reg, value, descr, type):
        cur = connection.cursor()
        ref = cur.callproc("PAYMENT.new_payment", [id, user, date_reg, value, 
    descr, type])
        cursor.close()
        return ref

在views.py中:

pay=PAYMENT()
x=pay.new_payment('123', '111', '2019-07-23', '10', 'test1', 'teste2')

此时,我得到错误:

“ORA-06550:第 1 行,第 7 列:PLS-00306:调用‘NEW_PAYMENT’时参数的数量或类型错误”`

任何提示我做错了什么?

【问题讨论】:

vc_arr 是什么类型?看起来像一个用户定义的集合,但你试图传递一个字符串 vc_arr 用于保存大量数据。 【参考方案1】:

OWA.vc_arr 看起来像一个集合,因此您需要将集合作为变量传递。 在cx_Oracle 文档中,您可以找到函数Cursor.arrayvar(dataType, value\[, size\])

创建一个与给定类型和大小的游标关联的数组变量,并返回一个变量对象。该值要么是一个整数,指定要分配的元素数量,要么是一个列表,分配的元素数量是从列表的大小中得出的。如果值是一个列表,该变量也被设置为列表的内容。如果未指定大小且类型为字符串或二进制,则分配 4000 字节。这对于将数组传递给 PL/SQL(在列表可能为空且无法自动确定类型的情况下)或从 PL/SQL 返回数组时是必需的。

所以你的代码可能看起来像:

class PAYMENT():
    def new_payment(self, id, user, date_reg, value, descr, type):
        cur = connection.cursor()
        u = cur.arrayvar(cx_Oracle.STRING,user)
        ds = cur.arrayvar(cx_Oracle.STRING,date_reg)
        v = cur.arrayvar(cx_Oracle.STRING,value)
        d = cur.arrayvar(cx_Oracle.STRING,descr)
        t = cur.arrayvar(cx_Oracle.STRING,type)
        ref = cur.callproc("PAYMENT.new_payment", [id, u, ds, v, 
    d, t])
        cursor.close()
        return ref

【讨论】:

以上是关于使用 callproc 从 django 调用 PL/SQL 过程的主要内容,如果未能解决你的问题,请参考以下文章

在 pymssql 中使用 `query` 和 `callproc` 调用存储过程的区别

通过 callproc 调用存储过程会导致缓存膨胀吗?

Django 创建多个 URL,为 POST 和 GET 调用相同的视图

使用 Python.h 从 C++ 调用 Django

jfinal调用oracle存储过程

从执行存储过程的psycopg2游标中获取列名列表?