2014-12-19 119 views
0

我正在使用pyodbc(版本3.0.7)来访问Oracle(版本11g)数据库。我们正在编写存储过程来处理插入。插入对象的主键分配有触发器,所以我们希望在python脚本调用存储过程之后,将新插入的对象的主键放到python中。 (由于客户要求,我们没有更改数据库,库等的灵活性)通过pyodbc从Oracle存储过程插入获取结果

根据pyodbc文档,不支持存储过程中的返回(OUT)参数。既没有存储功能。文档建议将SELECT语句添加到存储过程的末尾以获取结果。但是,我们对SQL脚本不熟悉,Google搜索过去两天已经为SQLServer和其他数据库提供了大量信息,但Oracle几乎没有。在Oracle数据库中尝试使用SQLServer示例并没有太大的帮助,因为Oracle SQL Developer在语法中显示了各种错误(DECLARE不应该是INL语句,INTO语句必须使用INTO等)。

最终,我们希望存储过程插入一个新对象,然后我们想以某种方式获取该对象的新创建的主键。

下面是正确地插入一个对象(注意,如果obj_id被给定为在python“无”,则该对象被触发分配一个新的主密钥)的存储过程的一个例子:

CREATE OR REPLACE PROCEDURE insert_an_obj (an_obj_id NUMBER) AS 
    new_primary_key NUMBER; 
BEGIN 
    INSERT INTO OBJS (OBJ_ID) VALUES (an_obj_id) RETURNING OBJ_ID INTO new_primary_key; 

    -- A SELECT statement should go here in order to get the new value for new_primary_key. 
END insert_an_obj; 

假设存储过程结束时的SELECT语句会在下一次我的脚本调用cursor.fetchall()时使脚本获得所选内容的列表。但是,我一直无法得到这个工作。一些失败的SELECT实例(其中一个可能会去在存储过程中上述代替SELECT评论)包括以下内容:

-- These fail to compile because SQL Developer doesn't like them (though various sources online said that they work on SQLServer): 
SELECT * FROM OBJS WHERE OBJ_ID=new_primary_key; 
SELECT OBJ_ID FROM OBJS WHERE OBJ_ID=new_primary_key; 

就像我说的,我是新来的SQL,并有可能我只需要知道正确的语法来让SELECT语句在Oracle中很好地工作。有什么建议么?还是有什么我误解?

+2

与SQL Server不同,您不能只在存储过程中放入'SELECT'来将数据返回给客户端。在12.1中有一些额外的语法来支持这种未声明的'OUT sys_refcursor',但是因为你已经为11g标记了这个,所以这不适合你。在11g中,从存储过程返回数据的唯一方法是使用'OUT'参数。 –

+0

@JustinCave:我很害怕这个。非常有趣,发现我们需要做的事情受到客户需要的软件版本的阻碍...感谢您的帮助。 –

回答

0

正如Justin Cave在上面评论中所提到的,“你不能仅仅在存储过程中使用SELECT来将数据返回给客户端。”至少与Oracle 11g不同。他继续说道:“在11g中,从存储过程中重新生成数据的唯一方法是使用OUT参数”,AFIK不能使用pyodbc的3.0.7版本。