gpt4 book ai didi

oracle - 获取 Oracle 数据库上插入的 recordid

转载 作者:行者123 更新时间:2023-12-02 08:38:51 24 4
gpt4 key购买 nike

我在数据库服务器上使用 Oracle,从 XP 客户端,使用 VB6 和 ADO。在一个事务中,我将一条记录插入到父表中,该父表具有触发器和序列来创建唯一的 recordid,然后该 recordid 用于与子表的关系,以便对子表进行可变数量的插入。为了提高性能,这是从我的客户端应用程序在一个执行命令中发送的。例如(简化示例):

declare Recordid int;  
begin
insert into ParentTable (_field list_) Values (_data list_);
Select ParentTableSequence.currVal into Recordid from dual;
insert into ChildTable (RecordID, _field list_) Values (Recordid, _data list_);
insert into ChildTable (RecordID, _field list_) Values (Recordid, _data list_);
... multiple, variable number of additional ChildTable inserts
commit;
end;

这工作正常。我的问题是:我还需要向客户端返回为插入创建的 Recordid。在 SQL Server 上,我可以在提交后向 Scope_Identity() 添加类似选择的内容,以将具有唯一 ID 的记录集返回给客户端。

但是我怎样才能为 Oracle 做类似的事情(不一定是记录集,我只需要那个长整数值)?我根据网络搜索的结果尝试了很多方法,但未能找到解决方案。

最佳答案

这两行可以压缩为一条语句:

--  insert into ParentTable (field list) Values (data list);
-- Select ParentTableSequence.currVal into Recordid from dual;
insert into ParentTable (field list) Values (data list)
returning ParentTable.ID into Recordid;

如果要将 ID 传递回调用程序,您需要将程序定义为存储过程或函数,分别将 Recordid 作为 OUT 参数或 RETURN 值返回。

编辑

MarkL 评论:

This is more of an Oracle PL/SQL question than anything else, I believe.

我承认我对 ADO 一无所知,所以我不知道以下示例是否适用于您的情况。它涉及构建一些基础设施,使我们能够将一组值传递到过程中。以下示例创建一个新部门,晋升一名现有员工来管理该部门,并分配两名新员工。

SQL> create or replace type new_emp_t as object
2 (ename varchar2(10)
3 , sal number (7,2)
4 , job varchar2(10));
5 /

Type created.

SQL>
SQL> create or replace type new_emp_nt as table of new_emp_t;
2 /

Type created.

SQL>
SQL> create or replace procedure pop_new_dept
2 (p_dname in dept.dname%type
3 , p_loc in dept.loc%type
4 , p_mgr in emp.empno%type
5 , p_staff in new_emp_nt
6 , p_deptno out dept.deptno%type)
7 is
8 l_deptno dept.deptno%type;
9 begin
10 insert into dept
11 (dname, loc)
12 values
13 (p_dname, p_loc)
14 returning deptno into l_deptno;
15 update emp
16 set deptno = l_deptno
17 , job = 'MANAGER'
18 , mgr = 7839
19 where empno = p_mgr;
20 forall i in p_staff.first()..p_staff.last()
21 insert into emp
22 (ename
23 , sal
24 , job
25 , hiredate
26 , mgr
27 , deptno)
28 values
29 (p_staff(i).ename
30 , p_staff(i).sal
31 , p_staff(i).job
32 , sysdate
33 , p_mgr
34 , l_deptno);
35 p_deptno := l_deptno;
36 end pop_new_dept;
37 /

Procedure created.

SQL>
SQL> set serveroutput on
SQL>
SQL> declare
2 dept_staff new_emp_nt;
3 new_dept dept.deptno%type;
4 begin
5 dept_staff := new_emp_nt(new_emp_t('MARKL', 4200, 'DEVELOPER')
6 , new_emp_t('APC', 2300, 'DEVELOPER'));
7 pop_new_dept('IT', 'BRNO', 7844, dept_staff, new_dept);
8 dbms_output.put_line('New DEPTNO = '||new_dept);
9 end;
10 /
New DEPTNO = 70

PL/SQL procedure successfully completed.

SQL>

DEPT 和 EMP 的主键都是通过触发器分配的。 FORALL 语法是一种非常有效的插入记录方法(它也适用于 UPDATEDELETE)。这可以写成一个FUNCTION来返回新的DEPTNO,但通常认为在插入、更新或删除时使用PROCEDURE是更好的做法。

这将是我首选的方法,但我承认这并不符合每个人的口味。

编辑2

就性能而言,使用 FORALL 的批量操作肯定会比少量单独插入执行得更好。在 SQL 中,集合操作始终优于逐条记录操作。但是,如果我们每次只处理少量记录,则很难注意到差异。

构建 PL/SQL 集合(您将其视为 SQL Server 中的临时表)在内存方面可能会很昂贵。如果有许多用户运行代码,则尤其如此,因为它来自 session 级别的内存分配,而不是共享全局区域。当我们处理大量记录时,最好分块填充数组,可能使用带有 LIMIT 子句的 BULK COLLECT 语法。

Oracle 在线文档集非常好。 PL/SQL 开发人员指南有一整章是关于集合的。 Find out more

关于oracle - 获取 Oracle 数据库上插入的 recordid,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1324761/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com