Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Oracle Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
 Можно ли вернуть через RETURNING более одной строки?  [new]
stil
Member

Откуда: Кемерово
Сообщений: 1295
Задача собственно такая:
Есть insert вставляющий в таблицу более 1 строки (фактически результат многострочного select). Primary key в таблице генерится через sequence в триггере.

После этого нужно в подчиненную таблицу вставить записи ссылающиеся на эти Pk. Нутром чуствую что задача типовая - но как это сделать проще всего? Можно ли вернуть в returning более одного значения?

Напрашивающийся способ построчного перебора результата первого селекта в курсорном цикле использовать бы не хотелось...
27 ноя 08, 13:57    [6494830]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли вернуть через RETURNING более одной строки?  [new]
Elic
Member

Откуда:
Сообщений: 29988
stil
Можно ли вернуть в returning более одного значения?
В принципе, да. Но не при insert...select :)
27 ноя 08, 14:00    [6494853]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли вернуть через RETURNING более одной строки?  [new]
stil
Member

Откуда: Кемерово
Сообщений: 1295
Elic
stil
Можно ли вернуть в returning более одного значения?
В принципе, да. Но не при insert...select :)

Единственный способ решения подобной задачи - курсорный цикл?

P. S. А в каком случае можно?
27 ноя 08, 14:03    [6494881]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли вернуть через RETURNING более одной строки?  [new]
Zloxa
Member

Откуда: СССР ☭
Сообщений: 1033
Если изучим диаграмму, увидим что returning_clause of single_table_insert может быть испльзована только совместно с values_clause, никак не с subquery
27 ноя 08, 14:05    [6494902]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли вернуть через RETURNING более одной строки?  [new]
Elic
Member

Откуда:
Сообщений: 29988
stil
Единственный способ решения подобной задачи - курсорный цикл?
Можно ещё попробовать
select bulk collect into 
forall 
  insert values returning
27 ноя 08, 14:08    [6494920]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли вернуть через RETURNING более одной строки?  [new]
stil
Member

Откуда: Кемерово
Сообщений: 1295
А что обозначает тогда эта фраза из концептов?
When operating on multiple rows, a DML statement with the returning_clause stores values from expressions, rowids, and REFs involving the affected rows in bind arrays.
слова вроде знакомые, но моск понимать отказывается...
27 ноя 08, 14:14    [6494999]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли вернуть через RETURNING более одной строки?  [new]
Elic
Member

Откуда:
Сообщений: 29988
stil
А что обозначает тогда эта фраза из концептов?
Что на то и правила, чтобы из них были исключения :)
А серьёзно, я сам не понимаю, почему Oracle так ограничил.
27 ноя 08, 14:17    [6495027]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли вернуть через RETURNING более одной строки?  [new]
orawish
Member

Откуда: Гадюкино-2 (City)
Сообщений: 15487
Elic
stil
Единственный способ решения подобной задачи - курсорный цикл?
Можно ещё попробовать
select bulk collect into 
forall 
  insert values returning

не, как раз не так, а:
insert into ляля select ..
RETURNING a,b BULK COLLECT INTO ..

балкон он только или на входе, или на выходе, но не с двух сторон сразу
27 ноя 08, 14:20    [6495044]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли вернуть через RETURNING более одной строки?  [new]
Elic
Member

Откуда:
Сообщений: 29988
orawish
не, как раз не так, а:
insert into ляля select ..
RETURNING a,b BULK COLLECT INTO ..
Золы наскрести или сам найдёшь, чем посыпаться?

P.S. Мой псевдокод - не из одного оператора :)
27 ноя 08, 14:24    [6495088]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли вернуть через RETURNING более одной строки?  [new]
orawish
Member

Откуда: Гадюкино-2 (City)
Сообщений: 15487
Elic
orawish
не, как раз не так, а:
insert into ляля select ..
RETURNING a,b BULK COLLECT INTO ..
Золы наскрести или сам найдёшь, чем посыпаться?

P.S. Мой псевдокод - не из одного оператора :)

согласен, мое выступление тут ~про прямой угол (золу сыплю )
27 ноя 08, 14:42    [6495216]     Ответить | Цитировать Сообщить модератору
Между сообщениями интервал более 1 года.
 Re: Можно ли вернуть через RETURNING более одной строки?  [new]
stil
Member

Откуда: Кемерово
Сообщений: 1295
returning with insert..select

The RETURNING DML clause can be extremely useful at times. Unfortunately, most of the times I've wanted to use it, it has been to return data from an INSERT..SELECT. For versions up to and including 11g Release 1, Oracle doesn't support this construct.

(c) http://www.oracle-developer.net/display.php?id=413
1 дек 10, 07:14    [9866513]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли вернуть через RETURNING более одной строки?  [new]
xtender
Member

Откуда: Мск
Сообщений: 5704
Можно так:


drop table t1;
drop table t2;
drop function f_seq;
drop sequence t_seq;
create table t1(id number, val number);
create table t2(id number, val number);
create sequence t_seq;
create function f_seq return number
is 
ret number;
begin
  select t_seq.nextval into ret from dual;
  return ret;
end;

insert all
  into t1
  into t2
select f_seq as id,level from dual connect by level<=10

select * from t1 join t2 on t1.id=t2.id
1 дек 10, 08:37    [9866637]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли вернуть через RETURNING более одной строки?  [new]
xtender
Member

Откуда: Мск
Сообщений: 5704
Тьфу, блин, не заметил как подключился к некропостеру...
1 дек 10, 08:39    [9866643]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли вернуть через RETURNING более одной строки?  [new]
stil
Member

Откуда: Кемерово
Сообщений: 1295
xtender
Тьфу, блин, не заметил как подключился к некропостеру...

Это не некропостинг. Просто запостил найденное недавно по случаю решение (правда только для поздних версий) старой проблемы, решение которой искал еще давно. На всякий.. Вдруг его еще ктото искать будет..

А насчет Вашего решения.. Так и не понял что Вы пытались сделать и как это относится к теме
1 дек 10, 13:21    [9868582]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли вернуть через RETURNING более одной строки?  [new]
_Nikotin
Member

Откуда: СПб
Сообщений: 2965
да и к тому же недавний баян insert select retuning bulk collect в одном запросе... КАК??
1 дек 10, 13:31    [9868676]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли вернуть через RETURNING более одной строки?  [new]
_Nikotin
Member

Откуда: СПб
Сообщений: 2965
xtender
Можно так:


[src oracle]...
create function f_seq return number
is
ret number;
begin
select t_seq.nextval into ret from dual;
return ret;
end;

insert all
into t1
into t2
select f_seq as id,level from dual connect by level<=10
...

а вот так опасно, где гарантии что f_seq не посчитается два раза для каждой таблицы?
1 дек 10, 14:23    [9869225]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли вернуть через RETURNING более одной строки?  [new]
xtender
Member

Откуда: Мск
Сообщений: 5704
_Nikotin, с чего он будет считаться отдельно для каждой таблицы?
1 дек 10, 14:27    [9869261]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли вернуть через RETURNING более одной строки?  [new]
bigsov
Member

Откуда:
Сообщений: 282
xtender, тот же результат получить можно и без функции:

insert all
  into t1 values (t_seq.nextval,l)
  into t2 values (t_seq.nextval,l)  -- или как вариант t_seq.currval
select level l from dual connect by level<=10

а задачу ТС можно решить с помощью insert all примерно так: 7512735
но к сожалению при условии отсуствия вызовов сиквенса из других сессий.
1 дек 10, 14:56    [9869516]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли вернуть через RETURNING более одной строки?  [new]
_Nikotin
Member

Откуда: СПб
Сообщений: 2965
xtender,

с того что не документировано обратное :)
1 дек 10, 14:59    [9869546]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли вернуть через RETURNING более одной строки?  [new]
stil
Member

Откуда: Кемерово
Сообщений: 1295
bigsov
но к сожалению при условии отсуствия вызовов сиквенса из других сессий.

Ну дык... Если б других сессий не было б - это бы была другая задача
1 дек 10, 15:04    [9869592]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли вернуть через RETURNING более одной строки?  [new]
bigsov
Member

Откуда:
Сообщений: 282
stil
bigsov
но к сожалению при условии отсуствия вызовов сиквенса из других сессий.

Ну дык... Если б других сессий не было б - это бы была другая задача
а где в условии задачи сказано про конкуренцию?
1 дек 10, 15:06    [9869621]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли вернуть через RETURNING более одной строки?  [new]
stil
Member

Откуда: Кемерово
Сообщений: 1295
bigsov,

Кроме того, я не могу использовать так сиквенс. У меня триггером pk генерится...

P.S. В общем понятно что решений много, но все так или иначе кривые..
1 дек 10, 15:08    [9869637]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли вернуть через RETURNING более одной строки?  [new]
stil
Member

Откуда: Кемерово
Сообщений: 1295
bigsov
а где в условии задачи сказано про конкуренцию?

Но и обратное тоже не сказано Хорошо - признаю неполноту описания...
1 дек 10, 15:10    [9869657]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли вернуть через RETURNING более одной строки?  [new]
_Nikotin
Member

Откуда: СПб
Сообщений: 2965
stil
bigsov
а где в условии задачи сказано про конкуренцию?

Но и обратное тоже не сказано Хорошо - признаю неполноту описания...

Протестую, наличие конкуренции это DEFAULT значение, а вот всякие ЕTL надо обговаривать отдельно.
1 дек 10, 15:13    [9869677]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли вернуть через RETURNING более одной строки?  [new]
_Nikotin
Member

Откуда: СПб
Сообщений: 2965
xtender,

А если почитать документацию

SQL Language Reference
For each INSERT ... [ALL | FIRST] statement (multitable insert). A multitable insert is considered a single SQL statement. Therefore, a reference to the NEXTVAL of a sequence will increase the sequence only once for each input record coming from the SELECT portion of the statement. If NEXTVAL is specified more than once in any part of the INSERT ... [ALL | FIRST ] statement, then the value will be the same for all insert branches, regardless of how often a given record might be inserted.


то можно сделать так

drop table t1;
drop table t2;
drop sequence t_seq;
create table t1(id number, val number);
create table t2(id number, val number);
create sequence t_seq;

insert all
  into t1 values(t_seq.nextval, L)
  into t2 values(t_seq.nextval, L)
select level L from dual connect by level<=10;

select * from t1 join t2 on t1.id=t2.id;
1 дек 10, 16:56    [9870705]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Oracle Ответить