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

Откуда:
Сообщений: 29
Добрый день
Всегда путаюсь, когда есть коллекции, селекты из них и т.д...

Есть следующие объекты:

type ONE_RECORD is object
  (
    name varchar2(240),
    link varchar2(240),  
    ....  --остальные поля
  );
  
type TABLE_RECORDS is table of ONE_RECORD;

procedure TEST_PROC (p_links in Table_Records)
begin
  for i in p_links.first..p_links.last 
    loop
    /*последовательность действий*/ 
    end loop;
end;

т.о. действия над записями массива p_links выполняются последовательно с первой по последнюю запись
мне же надо, чтобы эти действия выполнялись согласно определенному порядку, который прописан в следующей таблице

create table RIGHT_ORDER 
  (
    name varchar2(240),
    order_num   number
  );

т.е. например в массиве p_links следующие записи:

name, link
'Иванов', 'www.ivanov.ru'
'Петров', 'www.petrov.ru'
'Сидоров', 'www.sidorov.ru'

будет выполнена последовательность действий сначала с записью 'Иванов', затем с 'Петров', и т.д.

в RIGHT_ORDER следующие записи
name, order_num
'Иванов', 2
'Петров', 3
'Сидоров', 1

т.е. конечный результат - действия сначала над записью 'Сидоров', потом 'Иванов' и т.д.

как мне в процедуре прописать селект?
procedure TEST_PROC (p_links in Table_Records)
begin
  for i in (SELECT ro.order_num, plinks.name, plinks.link
             FROM
              (select p_links.name name, p_links.link link
               from table (p_links)) plinks,
              right_order ro
            WHERE ro.name=plinks.name
            ORDER BY ro.order_num)
    loop
    /*последовательность действий*/ 
    end loop;
end;

не получается, пишет Local collection types not allowed in SQL statements
18 июл 07, 15:02    [4404448]     Ответить | Цитировать Сообщить модератору
 Re: SELECT, объединяющий вложенную и обычную таблицу  [new]
dmidek
Member

Откуда: Киев - Дортмунд
Сообщений: 116070
Annika
не получается, пишет Local collection types not allowed in SQL statements


Ну так Oracle Вам же все сказал.
Вам нужно создать тип как SQL- тип - CREATE TYPE ...
18 июл 07, 15:07    [4404503]     Ответить | Цитировать Сообщить модератору
 Re: SELECT, объединяющий вложенную и обычную таблицу  [new]
Annika
Member

Откуда:
Сообщений: 29
Я не очень поняла, к сожалению...
Что ругается именно на p_links - это понятно
Если кому не трудно, напишите, плиз, на примере
18 июл 07, 15:29    [4404700]     Ответить | Цитировать Сообщить модератору
 Re: SELECT, объединяющий вложенную и обычную таблицу  [new]
Alexei_Unregistered
Guest
Бага от Oracle8i, нужно использовать cast:

... from table (cast(p_links as Table_Records)) ...
19 июл 07, 11:12    [4408191]     Ответить | Цитировать Сообщить модератору
 Re: SELECT, объединяющий вложенную и обычную таблицу  [new]
Annika
Member

Откуда:
Сообщений: 29
У меня Oracle 10g:)..
Использую cast, тогда ругается на тип TABLE_RECORDS, что invalid_datatype
19 июл 07, 14:25    [4409957]     Ответить | Цитировать Сообщить модератору
 Re: SELECT, объединяющий вложенную и обычную таблицу  [new]
Дубовая голова
Member [заблокирован]

Откуда: с цепи сорвался
Сообщений: 1821
Annika
Если кому не трудно, напишите, плиз, на примере


Вам уважаемый dmidek все уже объяснил:

SQL> create type ONE_RECORD is object
  2    (
  3      name varchar2(240),
  4      link varchar2(240)
  5    );
  6  /

Type created.

SQL> create type TABLE_RECORDS is table of ONE_RECORD;
  2  /

Type created.
19 июл 07, 14:34    [4410020]     Ответить | Цитировать Сообщить модератору
 Re: SELECT, объединяющий вложенную и обычную таблицу  [new]
Andrei Fomichev
Member

Откуда: Москва
Сообщений: 453
+ еще удалить из пакета строку
type TABLE_RECORDS is table of ONE_RECORD;

и все заработает.
19 июл 07, 14:36    [4410030]     Ответить | Цитировать Сообщить модератору
 Re: SELECT, объединяющий вложенную и обычную таблицу  [new]
Annika
Member

Откуда:
Сообщений: 29
Поняла наконец-то
Что проблема в том, что тип объявлен в пакете, а не как SQL-тип
Теперь другая проблема
Локальный тип был объявлен так
type ONE_RECORD is record
       (
        name varchar2(240),
        link varchar2(240)
        is_active  boolean
       );
Создаем SQL-тип
CREATE OR REPLACE type ONE_RECORD as object
       (
        name varchar2(240),
        link varchar2(240)
        is_active  boolean
       );
ругается на is_active boolean, "illegal type used for object type attribute Boolean"
а что, в объектном типе нет для его полей такого типа данных, как boolean?
19 июл 07, 15:21    [4410425]     Ответить | Цитировать Сообщить модератору
 Re: SELECT, объединяющий вложенную и обычную таблицу  [new]
Annika
Member

Откуда:
Сообщений: 29
CREATE OR REPLACE type ONE_RECORD as object
       (
        name varchar2(240),
        link varchar2(240),
        is_active  boolean
       );

запятую пропустила, когда щас сюда писала, т.е. дело не в ней
19 июл 07, 15:23    [4410434]     Ответить | Цитировать Сообщить модератору
 Re: SELECT, объединяющий вложенную и обычную таблицу  [new]
Annika
Member

Откуда:
Сообщений: 29
Т.е. тип создается, но потом смотришь - он не валидный, компилишь - и выдается ошибка про boolean
19 июл 07, 15:24    [4410449]     Ответить | Цитировать Сообщить модератору
 Re: SELECT, объединяющий вложенную и обычную таблицу  [new]
dmidek
Member

Откуда: Киев - Дортмунд
Сообщений: 116070
Annika

а что, в объектном типе нет для его полей такого типа данных, как boolean?


Нет. SQL не поддерживает работу с BOOLEAN.
Можете сэмулировать: NUMBER(1) - 1/0 VARCHAR2(1) - Y/N
19 июл 07, 15:24    [4410452]     Ответить | Цитировать Сообщить модератору
 Re: SELECT, объединяющий вложенную и обычную таблицу  [new]
Annika
Member

Откуда:
Сообщений: 29
Спасибо за ответы:) Запрос выполняется, попробую теперь разгрести дальше
19 июл 07, 16:07    [4410890]     Ответить | Цитировать Сообщить модератору
 Re: SELECT, объединяющий вложенную и обычную таблицу  [new]
Annika
Member

Откуда:
Сообщений: 29
Теперь проблема уже в другом

create type NEW_RECORD is object
       (
        name varchar2(240),
        link varchar2(240),
        is_active varchar2(1)
        );
create type NEW_TABLE_RECORDS is table of NEW_RECORD;

Из-за проблем с boolean я хотела объявить новую переменную v_new типа NEW_TABLE_RECORDS, а затем сделать финт ушами:
procedure TEST_PROC (p_links in Table_Records)
begin

 for i in p_links.first..p_links.last    
   loop
     select NEW_RECORD (
                         p_links(i).name,
                         p_links(i).link,
                         'N') 
     bulk collect
     into v_new
     from dual;
   end loop;

 for f in v_new.first..v_new.last 
    loop
    /*изначально требуемая последовательность действий*/ 
    end loop;

end;

берется первая запись p_links.first, значения полей присваиваются соответствующим полям в записи в v_new

а дальше-то я хотела, чтобы взялась вторая запись p_links.first+1, и тоже записалась в v_new, и т.д. до p_links.last
и дальше уже я буду работать с массивом v_new
а получилась такая фигня, что в v_new записались не 5 строк, а только 1, причем последняя, т.е. каждая последущая затирала собой предыдущую
как этого избежать?
19 июл 07, 17:43    [4411820]     Ответить | Цитировать Сообщить модератору
 Re: SELECT, объединяющий вложенную и обычную таблицу  [new]
Annika
Member

Откуда:
Сообщений: 29
Немножко ошиблась в предыдущем посте
Вот так я хотела сделать
Принцип тот же, синтаксис немножко не так записала

procedure TEST_PROC (p_links in Table_Records)
begin

 for i in p_links.first..p_links.last    
   loop
     select NEW_RECORD (
                         p_links(i).name,
                         p_links(i).link,
                         'N') 
     bulk collect
     into v_new
     from dual;
   end loop;

  for f in (SELECT ro.order_num, vnew.name, vnew.link
             FROM
              (select name, link
               from table (cast(v_new as NEW_TABLE_RECORDS))) vnew,
              right_order ro
            WHERE ro.name=plinks.name
            ORDER BY ro.order_num)
    loop
    /*изначально требуемая последовательность действий*/ 
    end loop;

end;
19 июл 07, 17:54    [4411903]     Ответить | Цитировать Сообщить модератору
 Re: SELECT, объединяющий вложенную и обычную таблицу  [new]
Annika
Member

Откуда:
Сообщений: 29
Т.е. проблема все еще насущная
В v_new вставляется только последняя запись из p_links
19 июл 07, 17:55    [4411914]     Ответить | Цитировать Сообщить модератору
 Re: SELECT, объединяющий вложенную и обычную таблицу  [new]
Jannny
Member

Откуда: Спб
Сообщений: 6424
Annika
а получилась такая фигня, что в v_new записались не 5 строк, а только 1, причем последняя, т.е. каждая последущая затирала собой предыдущую
как этого избежать?
не использовать bulk collect, писать позаписно
19 июл 07, 18:02    [4411973]     Ответить | Цитировать Сообщить модератору
 Re: SELECT, объединяющий вложенную и обычную таблицу  [new]
Annika
Member

Откуда:
Сообщений: 29
Т.е.
 for i in p_links.first..p_links.last    
   loop
     select  p_links(i).name,
               p_links(i).link,
               'N'
     into v_new
     from dual;
   end loop;

пишет not enough values, хотя значений хватает, если написать как
 for i in p_links.first..p_links.last    
   loop
     select NEW_RECORD (
                         p_links(i).name,
                         p_links(i).link,
                         'N') 
     bulk collect
     into v_new
     from dual;
   end loop;
то все нормально компилится
19 июл 07, 18:21    [4412114]     Ответить | Цитировать Сообщить модератору
 Re: SELECT, объединяющий вложенную и обычную таблицу  [new]
Wladislaw
Member

Откуда:
Сообщений: 245
У вас переменная
v_new
имеет тип
NEW_RECORD
, а должна либо иметь тип
NEW_TABLE_RECORDS
б либо уберите
bulk collect
из кода.
19 июл 07, 18:57    [4412327]     Ответить | Цитировать Сообщить модератору
 Re: SELECT, объединяющий вложенную и обычную таблицу  [new]
Wladislaw
Member

Откуда:
Сообщений: 245
Сорри, я был не прав в предыдущем сообщении, просто уберите bulk collect у себя в коде.
19 июл 07, 19:00    [4412340]     Ответить | Цитировать Сообщить модератору
 Re: SELECT, объединяющий вложенную и обычную таблицу  [new]
Annika
Member

Откуда:
Сообщений: 29
Т.е.
procedure TEST_PROC (p_links in Table_Records)
begin

 for i in p_links.first..p_links.last    
   loop
     select NEW_RECORD (
                         p_links(i).name,
                         p_links(i).link,
                         'N') 
     into v_new
     from dual;
   end loop;
20 июл 07, 12:05    [4414848]     Ответить | Цитировать Сообщить модератору
 Re: SELECT, объединяющий вложенную и обычную таблицу  [new]
Annika
Member

Откуда:
Сообщений: 29
не компилится
пишет inconsistent datatypes
20 июл 07, 12:06    [4414850]     Ответить | Цитировать Сообщить модератору
 Re: SELECT, объединяющий вложенную и обычную таблицу  [new]
Jannny
Member

Откуда: Спб
Сообщений: 6424
Annika
не компилится
пишет inconsistent datatypes
v_new(v_new.last+1) := ...
20 июл 07, 12:09    [4414871]     Ответить | Цитировать Сообщить модератору
 Re: SELECT, объединяющий вложенную и обычную таблицу  [new]
Annika
Member

Откуда:
Сообщений: 29
Не поняла в какое место кода это вставить :(
20 июл 07, 12:41    [4415112]     Ответить | Цитировать Сообщить модератору
 Re: SELECT, объединяющий вложенную и обычную таблицу  [new]
Дубовая голова
Member [заблокирован]

Откуда: с цепи сорвался
Сообщений: 1821
Jannny
Annika
не компилится
пишет inconsistent datatypes
v_new(v_new.last+1) := ...


Пардон, что влез.
Если я ничего нигде не упустил (многа букофф, ниасилил) - нужна инициализация
и единичный extend

SQL> create type new_object is object(link varchar2(10),
  2  name varchar2(10), status char(1))
  3  /

Type created.

SQL> create type new_object_table is table of new_object
  2  /

Type created.

SQL> create type new_record is object(link varchar2(10), name varchar2(10))
  2  /

Type created.

SQL> create type new_record_table is table of new_record
  2  /

Type created.

SQL> declare
  2   p_links new_Record_table := new_Record_table(
  3     new_record('a','a'),
  4     new_record('b','b'));
  5  
  6   v_new new_object_table := new_object_table();
  7  
  8  begin
  9  
 10   v_new.extend(p_links.count);  
 11   
 12   for i in 1..p_links.count loop  
 13       v_new(i) := NEW_OBJECT (p_links(i).name,
 14                           p_links(i).link,
 15                           'N'); 
 16   end loop;
 17  
 18  end;
 19  /

PL/SQL procedure successfully completed.
20 июл 07, 12:57    [4415256]     Ответить | Цитировать Сообщить модератору
 Re: SELECT, объединяющий вложенную и обычную таблицу  [new]
Annika
Member

Откуда:
Сообщений: 29
Огромное всем спасибо, все поперло:)
20 июл 07, 13:26    [4415504]     Ответить | Цитировать Сообщить модератору
Все форумы / Oracle Ответить