Эти две строки могут быть сжаты в один оператор:
-- 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;
Если вы хотите передать идентификатор обратно вызывающей программе, вам необходимо определить свою программу как хранимую процедуру или функцию, возвращая Recordid в качестве параметра OUT или значения RETURN соответственно.
Редактировать
MarkL прокомментировал:
Это больше Oracle PL / SQL
вопрос чем что-либо еще, я
верить.
Признаюсь, я ничего не знаю об 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
является очень эффективным способом вставки записей (он также работает для UPDATE
и DELETE
). Это может быть записано как FUNCTION
для возврата нового DEPTNO вместо этого, но обычно считается лучшей практикой использовать PROCEDURE
при вставке, обновлении или удалении.
Это был бы мой предпочтительный подход, но я признаю, что это не всем по вкусу.
Редактировать 2
Что касается производительности, массовые операции с использованием FORALL
определенно будут выполняться лучше, чем несколько отдельных вставок. В SQL операции set всегда предпочтительнее, чем запись за записью. Однако, если мы имеем дело только с несколькими записями каждый раз, может быть трудно заметить разницу.
Создание коллекции PL / SQL (которую вы считаете временной таблицей в SQL Server) может быть дорогостоящим с точки зрения памяти. Это особенно верно, если код выполняется многими пользователями, потому что это происходит из-за выделения памяти на уровне сеанса, а не из общей глобальной области. Когда мы имеем дело с большим количеством записей, лучше заполнить массив кусками, возможно, используя синтаксис BULK COLLECT
с предложением LIMIT
.
Онлайн-документация Oracle довольно хороша. В Руководстве разработчика PL / SQL есть целая глава о коллекциях. Узнайте больше .