通过pyodbc从Oracle存储过程插入中获取结果

时间:2014-12-19 18:31:21

标签: sql oracle stored-procedures oracle11g pyodbc

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

根据pyodbc文档,不支持存储过程中的return(OUT)参数。两者都不是存储函数。文档建议在存储过程的末尾添加SELECT语句以获得结果。但是,我们是SQL脚本的新手,过去两天谷歌搜索已经为SQLServer和其他数据库提供了大量信息,但对Oracle来说几乎没有。在Oracle数据库上尝试SQLServer示例并没有太大的帮助,因为Oracle SQL Developer显示了语法的各种错误(DECLARE不应该是一个,SELECT语句需要INTO等)。

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

以下是正确插入对象的存储过程的示例(请注意,如果在python中将obj_id指定为“None”,则通过触发器为对象分配新的主键):

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中运行良好。有什么建议?或者有什么我误解的事情?

1 个答案:

答案 0 :(得分:0)

正如Justin Cave在上面的评论中所提到的,"你不能只在存储过程中放置​​一个SELECT来将数据返回给客户端。"至少不是Oracle 11g。他继续说道:"在11g中,从存储过程中重新调整数据的唯一方法是使用OUT参数",AFIK,使用pyodbc 3.0.7版本无法实现。