Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Oracle Новый топик    Ответить
 поведение конструкции forall  [new]
easylogic
Member

Откуда:
Сообщений: 12
День добрый.

Есть процедура в которой объявлено несколько pl/sql типов. В итоге есть конструкция:

forall j in tproduct_list_type_id.first .. tproduct_list_type_id.last
insert into cmc_product2list
(product_list_id, product_id, product_list_order)
select /*+ all_rows*/
tproduct_list_id(j),
ttt.product_id,
rownum - 1
from (select p.product_id,
count(*) as cnt
from cmc_order o,
cmc_order_product op,
cmc_product p
where op.order_id = o.order_id
and p.product_id = op.product_id
and o.order_status_id in (3, 4, 10)
and p.product_status_id = 2
and p.is_sold = '1'
and p.product_type_id in
(select p2t.product_type_id
from cmc_plt2pt p2t
where p2t.product_list_type_id =
tproduct_list_type_id(j))
and o.payment_date between sysdate - tdate_interval(j) and
sysdate
and nvl(o.retailer_id,
0) = nvl(tretailer_id(j),
0)
and ((tgenre_id(j) is null) or exists
(select 1
from cmc_genre2product g2p
where g2p.product_id = p.product_id
and g2p.genre_id = tgenre_id(j)))
group by p.product_id
order by cnt desc) ttt
where rownum <= tcontent_count(j);

В результате выполнения этого счастья я получил абсолютно неправильные данные. После того, как я заменил forall на обычный for ... loop все заработало нормально. Отсюда вывод: во время выполнения с forall Oracle не корректно подставлял значения из типов (в частности tcontent_count(j) в конце запроса). Кто-то может обьяснить или дать линк где почитать про столь необычное (лично для меня) поведение Oracle?

Заранее спасибо!
19 окт 07, 15:43    [4815881]     Ответить | Цитировать Сообщить модератору
 Re: поведение конструкции forall  [new]
Дубовая голова
Member [заблокирован]

Откуда: с цепи сорвался
Сообщений: 1821
easylogic
В результате выполнения этого счастья я получил абсолютно неправильные данные. После того, как я заменил forall на обычный for ... loop все заработало нормально. Отсюда вывод: во время выполнения с forall Oracle не корректно подставлял значения из типов (в частности tcontent_count(j) в конце запроса). Кто-то может обьяснить или дать линк где почитать про столь необычное (лично для меня) поведение Oracle?
Заранее спасибо!


Доказательства в студию.
19 окт 07, 15:47    [4815902]     Ответить | Цитировать Сообщить модератору
 Re: поведение конструкции forall  [new]
dmidek
Member

Откуда: Киев - Дортмунд
Сообщений: 116242
FORALL INSERT SELECT ?

А что, так можно ?
19 окт 07, 15:52    [4815937]     Ответить | Цитировать Сообщить модератору
 Re: поведение конструкции forall  [new]
Дубовая голова
Member [заблокирован]

Откуда: с цепи сорвался
Сообщений: 1821
dmidek

А что, так можно ?


Запросто. Только смысл самого селекта непрозрачен :)

автор

SQL> create table t_c as select * from t where 1=2;

Table created.

SQL> desc t
Name Null? Type
----------------------------------------- -------- -----------------------
ID NUMBER(38)
C1 NUMBER(38)
C2 NUMBER(38)
C3 NUMBER(38)

SQL> desc t_c
Name Null? Type
----------------------------------------- -------- -----------------------
ID NUMBER(38)
C1 NUMBER(38)
C2 NUMBER(38)
C3 NUMBER(38)

SQL> select count(1) from t;

COUNT(1)
----------
1

SQL> declare
2 type p is table of int index by pls_integer;
3 pp p;
4 begin
5
6 pp(1) := 1;
7
8 forall j in pp.first..pp.last
9 insert into t_c select * from t where rownum <= pp(j);
10
11 end;
12 /

PL/SQL procedure successfully completed.

19 окт 07, 15:56    [4815963]     Ответить | Цитировать Сообщить модератору
 Re: поведение конструкции forall  [new]
dmidek
Member

Откуда: Киев - Дортмунд
Сообщений: 116242
Дубовая голова
dmidek

А что, так можно ?


Запросто. Только смысл самого селекта непрозрачен :)


У автора select "обернутый".
Поэтому rownum <= не должно вызвать неоднозначности данных,
если Вы ее имели в виду...

У меня где- то в подкорке сидят воспоминания о косяках в структуре
FORALL INSERT SELECT . Но подтверждений найти пока не смог...
19 окт 07, 16:20    [4816099]     Ответить | Цитировать Сообщить модератору
 Re: поведение конструкции forall  [new]
easylogic
Member

Откуда:
Сообщений: 12
dmidek
Дубовая голова
dmidek

А что, так можно ?


Запросто. Только смысл самого селекта непрозрачен :)


У автора select "обернутый".
Поэтому rownum <= не должно вызвать неоднозначности данных,
если Вы ее имели в виду...

У меня где- то в подкорке сидят воспоминания о косяках в структуре
FORALL INSERT SELECT . Но подтверждений найти пока не смог...


Там именно в rownum и дело. Вместо того, чтоб получать 100, 20 или 5 записей я постоянно получаю 20. Самое интересное, что на простом примере не могу воссоздать картину...
19 окт 07, 16:31    [4816178]     Ответить | Цитировать Сообщить модератору
 Re: поведение конструкции forall  [new]
dmidek
Member

Откуда: Киев - Дортмунд
Сообщений: 116242
easylogic
dmidek
Дубовая голова
dmidek

А что, так можно ?


Запросто. Только смысл самого селекта непрозрачен :)


У автора select "обернутый".
Поэтому rownum <= не должно вызвать неоднозначности данных,
если Вы ее имели в виду...

У меня где- то в подкорке сидят воспоминания о косяках в структуре
FORALL INSERT SELECT . Но подтверждений найти пока не смог...


Там именно в rownum и дело. Вместо того, чтоб получать 100, 20 или 5 записей я постоянно получаю 20. Самое интересное, что на простом примере не могу воссоздать картину...


Может быть дело не в rownum, а в отселектированном наборе ?
Может быть в нем всего лишь 20 записей , а все остальные значения в
таблице tcontent_count больше ?
19 окт 07, 16:34    [4816202]     Ответить | Цитировать Сообщить модератору
 Re: поведение конструкции forall  [new]
Дубовая голова
Member [заблокирован]

Откуда: с цепи сорвался
Сообщений: 1821
easylogic

Там именно в rownum и дело. Вместо того, чтоб получать 100, 20 или 5 записей я постоянно получаю 20.


Что-то Вы, профессор, воля Ваша, непонятное придумали (c)

SQL> select * from emp_c;

no rows selected

SQL> declare
  2  
  3   type g is table of int index by pls_integer;
  4   pp g;
  5   gg g;
  6  begin
  7  
  8   gg(1) := 10;
  9   gg(2) := 20;
 10   gg(3) := 30;
 11  
 12   pp(1) := 1;
 13   pp(2) := 2;
 14   pp(3) := 3;
 15  
 16  
 17   forall j in pp.first..pp.last
 18    insert into emp_c select deptno, ename from emp 
 19    where deptno = gg(j) and rownum <= pp(j);
 20  
 21  end;
 22  /

PL/SQL procedure successfully completed.

SQL> select * from emp_c;

    DEPTNO ENAME
---------- ----------
        10 CLARK
        20 SMITH
        20 JONES
        30 ALLEN
        30 WARD
        30 MARTIN

6 rows selected.
19 окт 07, 17:21    [4816564]     Ответить | Цитировать Сообщить модератору
Все форумы / Oracle Ответить