我正在使用pyodbc(版本3.0.7(访问Oracle(版本11g(数据库。 我们正在编写存储过程来处理插入。 插入对象的主键分配有触发器,因此我们希望在 python 脚本调用存储过程后将新插入对象的主键获取到 python 中。(由于客户要求,我们无法灵活更改数据库、库等(
根据 pyodbc 文档,不支持存储过程中的返回 (OUT( 参数。 存储函数也不是。 该文档建议在存储过程的末尾添加 SELECT 语句以获取结果。 然而,我们是SQL脚本的新手,谷歌搜索了过去两天的SQLServer和其他数据库的大量信息,但Oracle几乎没有。 在 Oracle db 上尝试 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中很好地工作。 有什么建议吗? 还是我误解了什么?
正如 Justin Cave 在上面的评论中提到的,"你不能只是在存储过程中放置一个SELECT
来将数据返回给客户端。 至少在甲骨文11g中不是。 他继续说道:"在 11g 中,从存储过程中提取数据的唯一方法是有一个OUT
参数",AFIK 无法使用 pyodbc 的 3.0.7 版。