Модераторы: LSD
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> VARRAY в запросе 
:(
    Опции темы
setnull
Дата 10.2.2009, 12:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 417
Регистрация: 3.7.2007

Репутация: 1
Всего: 1



Все здрваствуйте.


такая тема:

Код

DECLARE

type ar_type is varray(100) of nummber;
an_array ar_type;

an_array := ar_type(1, 2, 3)


begin

select
    ...........
    ..........
    CASE 
        WHEN ROWNUM <=3 THEN an_array(ROWNUM )
        ELSE null
    END
    
from my_table


Только, если записей болльше 3х, все равно вылетает
ORA-06532: Subscript outside of limit.

Он че просчитует THEN даже если WHEN не проходит?????????

И еще. Как узнать длинну массива? an_array.length или как? Чтоб не жестко 3 прописывать?

Спасибо!!!!!!!!!
PM MAIL   Вверх
DimW
Дата 10.2.2009, 13:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1330
Регистрация: 24.2.2005
Где: Орёл

Репутация: 23
Всего: 44



Цитата(setnull @  10.2.2009,  12:51 Найти цитируемый пост)
Как узнать длинну массива?

Код

declare
  type ar_type is varray(100) of number;
  an_array ar_type;
begin
  an_array := ar_type(1, 2, 3);
  dbms_output.put_line(an_array.last);
end;

PM MAIL ICQ   Вверх
Zloxa
Дата 10.2.2009, 13:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Чо?
****


Профиль
Группа: Завсегдатай
Сообщений: 3473
Регистрация: 12.9.2008

Репутация: 37
Всего: 161



Код

Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 

create or replace function foo(v number) return number
is
begin
  dbms_output.put_line('Rownum='||v);
  return v;
end;
/
 
Function created
DECLARE
  type ar_type is varray(100) of number;
  an_array ar_type;
  f number;
begin
  an_array := ar_type(1, 2, 3);
  for i in (select
             an_array(foo(rownum))
            from dual
           )
  loop
   null;
  end loop;
end;
/
 
Rownum=0

ORA-06532: Subscript outside of limit
ORA-06512: at line 8
 
 


По всему видать ROWNUM рассчитывается ПОСЛЕ формирования строки фетча.
На 9.2.0.8 - тоже самое
Объяснить пока не могу, надо медитировть, но, полагаю, это фича а не баг


--------------------
Достоверно известно, что 89% людей доверяют статистике взятой с потолка smile
PM   Вверх
Zloxa
Дата 10.2.2009, 13:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Чо?
****


Профиль
Группа: Завсегдатай
Сообщений: 3473
Регистрация: 12.9.2008

Репутация: 37
Всего: 161



Результат медитации (сугубо мое ИМХО) таков:
an_array из pl_sql машины передается в sql машину связанной переменной.
значения связанных переменных вычисляются до выполнения запроса. Т.е. на том этапе, когда rownum еще и в проекте нет.
Почему я сделал такой вывод
Смотрим скрипт:
Код

DECLARE
  type ar_type is varray(100) of number;
  an_array ar_type;
  f number;
begin
  an_array := ar_type(-1, -2, -3);
  for i in (select an_array(1)
                   ,'kjlkjjjjl1'
            from dual
           )
  loop
    null;
  end loop;
  for i in (select an_array(rownum)
                   ,'kjlkjjjjl2'
            from dual
           )
  loop
    null;
  end loop;
end;
 
ORA-06532: Subscript outside of limit
ORA-06512: at line 15
select sql_text from v$sql where sql_text like 'SELECT%kjlkjjjjl%';
 
SQL_TEXT
--------------------------------------------------------------------------------
SELECT :B1 ,'kjlkjjjjl1' FROM DUAL

Как мы видим, первый запрос был разобран и pl/sql массив был ему передан в качестве бинда как значение, а не как массив
Второй запрос даже не был разобран. Т.е. ошибка произошла на этапе разбора - до выполнения запроса.. Следовательно функцию foo вызвал pl/sql движок а не SQL. Отчего он не руганулся на rownum - мне не понятно.

ЗЫ спасибо за интересный пример.


Это сообщение отредактировал(а) Zloxa - 10.2.2009, 14:00


--------------------
Достоверно известно, что 89% людей доверяют статистике взятой с потолка smile
PM   Вверх
DimW
Дата 10.2.2009, 14:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1330
Регистрация: 24.2.2005
Где: Орёл

Репутация: 23
Всего: 44



Цитата(setnull @  10.2.2009,  12:51 Найти цитируемый пост)
Он че просчитует THEN даже если WHEN не проходит?????????

причина в том что rownum это псевдо столбуц который формируется после from и where по этому на момент выполнения sql значение для параметра :Var1  запроса - "select case when (rownum <= :Var2) then :Var1 else null end test_field from dual" нет.
именно в :Var1 преобразуется an_array(rownum).

в этом можно убедиться изучив результат запроса:
Код

select * from v$sql t where t.SQL_TEXT like '%WHEN ROWNUM <=3 THEN%' -- (примерно так)


PM MAIL ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Oracle"
Zloxa
LSD

Данный раздел предназначен для обсуждения проблем с Oracle Database, другие продукты Oracle здесь не обсуждаются. Просьба при создании темы, придерживаться следующих правил:

  • при создании темы давайте ей осмысленное название, описывающее суть проблемы
  • указывайте используемую версию базы, способ соединения и язык программирования
  • при ошибках обязательно приводите код ошибки и сообщение сервера
  • приводите код в котором возникла ошибка, по возможности дайте тестовый пример демонстрирующий ошибку
  • при вставке кода используйте соответсвующие теги: [code=sql] [/code] для подсветки SQL и PL/SQL кода, [code=java] [/code] - для Java, и т.д.

  • документация по Oracle: 9i, 10g, 11g
  • книги по Oracle можно поискать здесь
  • действия модераторов можно обсудить здесь

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Zloxa, LSD.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Oracle | Следующая тема »


 




[ Время генерации скрипта: 0.0474 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.