ROWID в отлитой коллекции pl-sql

Есть ли в коллекции pl-sql средство, похожее на rowid? В моем случае, когда я использую эту коллекцию в запросе sql, мне также нужен порядковый номер по мере их ввода. Я знаю, что изменение - это структура данных, но я хочу использовать индекс коллекции. так что я ищу что-то вроде этого:

TYPE t_List IS TABLE OF VARCHAR2(200);

а также

declare
v_Data t_List := t_List('data 1'
                       ,'data_2'
                       ,'data3');
......

FOR Rec IN (SELECT Column_Value v
                  ,ROWID        r
            FROM   TABLE(CAST(v_data t_list)))
LOOP
    Dbms_Output.Put_Line('at ' || Rec.r || ':' || Rec.v);
    -- .... and other codes here
END LOOP;

Не предполагается, что цикл будет выполняться последовательно, но я хочу что-то встроенное, например, ROWID, подобное индексу коллекции.

2 ответа

Решение

Только операторы уровня схемы могут использоваться в операторе SQl, даже в пределах блока PL/SQL. Как вы предполагаете, вы уже знаете, вы можете создать свой собственный тип объекта, который включает в себя идентификатор "sequence":

CREATE TYPE t_object AS OBJECT (
  id NUMBER,
  data VARCHAR2(200)
)
/

И коллекция такого типа:

CREATE TYPE t_List IS TABLE OF t_object;
/

А затем заполните идентификатор при создании списка:

DECLARE
  l_List t_List := t_List(t_object(1, 'data 1')
                         ,t_object(2, 'data_2')
                         ,t_object(3, 'data3'));
BEGIN
  FOR Rec IN (SELECT id, data
              FROM   TABLE(l_list))
  LOOP
    Dbms_Output.Put_Line('at ' || Rec.id || ':' || Rec.data);
    -- .... and other codes here
  END LOOP;
END;
/

Без типа объекта вы можете использовать ROWNUM псевдостолбец:

CREATE TYPE t_List IS TABLE OF VARCHAR2(200);
/

DECLARE
  v_Data t_List := t_List('data 1'
                         ,'data_2'
                         ,'data3');
BEGIN
  FOR Rec IN (SELECT Column_Value v
                    ,ROWNUM       r
              FROM   TABLE(v_data))
  LOOP
      Dbms_Output.Put_Line('at ' || Rec.r || ':' || Rec.v);
      -- .... and other codes here
  END LOOP;
END;
/

anonymous block completed
at 1:data 1
at 2:data_2
at 3:data3

Насколько я знаю, это не гарантирует сохранение первоначальной последовательности создания. Я думаю, что это почти наверняка будет в данный момент, но, возможно, это не то, на что вы должны полагаться, как всегда, чтобы быть правдой. ( Там нет порядка безorder by, но здесь у вас нет ничего, что вы можете заказать, не разрушив ваш первоначальный заказ...).

Если вы запрашиваете подмножество таблицы - я не уверен, что вы подразумеваете под "цикл не должен выполняться последовательно" - вам нужно сгенерировать ROWNUM в подзапросе перед фильтрацией, иначе он не будет согласованным. Вам также необходимо сгенерировать ROWNUM в подзапросе, если вы объединяете это с другими реальными таблицами - я полагаю, что вы есть, иначе вы можете использовать коллекцию PL/SQL.

Если индексация важна, используйте ассоциативные массивы (также известные как таблицы Index-by)

Отсылаю его.

Другие вопросы по тегам