powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Странное поведение переменных в пакетах, с большим количеством строк
25 сообщений из 77, страница 2 из 4
Странное поведение переменных в пакетах, с большим количеством строк
    #39566197
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ivan Rabashchenko...Просто в начале пакета сделать фейковую функцию вида...
IMHO жесть какая
Не проще пакет на несколько пакетов разделить?

Ну и самый интересный вопрос: а что говорит Oracle Support на эту багу?
...
Рейтинг: 0 / 0
Странное поведение переменных в пакетах, с большим количеством строк
    #39566240
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
А эти неправильные значения в коде не встречаются случайно? Может тупо переполнение индекса идет
...
Рейтинг: 0 / 0
Странное поведение переменных в пакетах, с большим количеством строк
    #39566242
Ivan Rabashchenko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Леонид, нет не проще.
Для этого нужно изменить не только код генератора пакетов, но и всю парадигму системы, а это тьма кода, который работает поверх этих нелепых, неповоротливых, гигантских пакетов. К этому добавлю, что нарвались мы на этот bug только лишь у одного клиента (а их сонм), у которого и OS и БД знакомые (связка такая много у кого Solaris + 11.2.0.4) и затевать глобальный рефакторинг это очень смелый и дорогой шаг. Возможно, обойдемся малой кровью. Сначала решил сам поколупаться - не получилось (не хватает знания матчасти) , затем решил спросить умных людей (спасибо всем кто откликается), если решения не найдем, зарегим официальную ноту на Oracle Support.
...
Рейтинг: 0 / 0
Странное поведение переменных в пакетах, с большим количеством строк
    #39566247
Ivan Rabashchenko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
xtenderА эти неправильные значения в коде не встречаются случайно? Может тупо переполнение индекса идет

Вполне возможно, на сегодня забрали доступ, завтра с утра предоставлю такую информацию.
...
Рейтинг: 0 / 0
Странное поведение переменных в пакетах, с большим количеством строк
    #39566248
MaximaXXL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ivan Rabashchenko,

А можете попробовать с числом 268435455 и написать полученный результат?
...
Рейтинг: 0 / 0
Странное поведение переменных в пакетах, с большим количеством строк
    #39566256
Ivan Rabashchenko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
MaximaXXLIvan Rabashchenko,

А можете попробовать с числом 268435455 и написать полученный результат?

Мне наверное стоило в моем первом комментарии уточнить вот такой факт:
Если оперировать не большими числами, например:

Код: plsql
1.
2.
3.
4.
5.
6.
function fIr$Tmp return number is
nRes number;
begin        
  nRes :=  268;
  return nRes;
end;



то все работает корректно независимо от положения в пакете. А если 268435456, например, то натыкаемся на некорректное поведение. Чтобы было понятнее, структура пакета такая:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
......
function fIr$Tmp_110 return number is 
nRes number;
begin        
  nRes :=  268435456;
  return nRes;
end;
function fIr$Tmp_111 return number is 
nRes number;
begin        
  nRes :=  268;
  return nRes;
end;
function fIr$Tmp_112 return number is 
nRes number;
begin        
  nRes :=  268435457;
  return nRes;
end;
......




и получается, что fIr$Tmp_110 и fIr$Tmp_112 возвращают ересь, а fIr$Tmp_111 - норм.
...
Рейтинг: 0 / 0
Странное поведение переменных в пакетах, с большим количеством строк
    #39566262
Фотография dbms_photoshop
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Расплющенная принцессаIvan RabashchenkoStarting with release 7.3.4, the DIANA for package bodies is thrown away, not used, and not stored in the databaseЭто откуда? Смотри в доке plsql лимиты, там есть что посчитать. По объему parsed_code грозятся ошибкой pls-123.
И она даже возникает.
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
declare
   n           integer := 6551;
   spec_list   dbms_sql.varchar2a;
   body_list   dbms_sql.varchar2a;
   l_cursor    integer default dbms_sql.open_cursor;
   res         integer;
begin
   spec_list(1)                     := 'create or replace package pkg as';
   for i in 1 .. n
   loop
      spec_list(spec_list.count + 1):= 'function f' || i || ' return number;';
   end loop;
   spec_list(spec_list.count + 1)   := 'end;';
   dbms_sql.parse(l_cursor, spec_list, spec_list.first, spec_list.last, true, dbms_sql.native);
   res                              := dbms_sql.execute(l_cursor);

   body_list(1)                     := 'create or replace package body pkg as';
   for i in 1 .. n
   loop
      body_list(body_list.count + 1):= 'function f' || i || ' return number as
                                        begin return ' || i || '; end;';
   end loop;
   body_list(body_list.count + 1)   := 'end;';
   dbms_sql.parse(l_cursor, body_list, body_list.first, body_list.last, true, dbms_sql.native);
   res                              := dbms_sql.execute(l_cursor);
end;
/

PL/SQL procedure successfully completed.

select pkg.f6551 from dual;

     F6551
----------
      6551

declare
   n           integer := 6552;
   spec_list   dbms_sql.varchar2a;
   body_list   dbms_sql.varchar2a;
   l_cursor    integer default dbms_sql.open_cursor;
   res         integer;
begin
   spec_list(1)                     := 'create or replace package pkg as';
   for i in 1 .. n
   loop
      spec_list(spec_list.count + 1):= 'function f' || i || ' return number;';
   end loop;
   spec_list(spec_list.count + 1)   := 'end;';
   dbms_sql.parse(l_cursor, spec_list, spec_list.first, spec_list.last, true, dbms_sql.native);
   res                              := dbms_sql.execute(l_cursor);

   body_list(1)                     := 'create or replace package body pkg as';
   for i in 1 .. n
   loop
      body_list(body_list.count + 1):= 'function f' || i || ' return number as
                                        begin return ' || i || '; end;';
   end loop;
   body_list(body_list.count + 1)   := 'end;';
   dbms_sql.parse(l_cursor, body_list, body_list.first, body_list.last, true, dbms_sql.native);
   res                              := dbms_sql.execute(l_cursor);
end;
/

PL/SQL procedure successfully completed.

alter package pkg compile;

Warning: Package altered with compilation errors.

sho err
Errors for PACKAGE PKG:

LINE/COL ERROR
-------- -----------------------------------------------------------------
1/1      PLS-00123: program too large (Diana nodes)


Linux, 11.2.0.4
...
Рейтинг: 0 / 0
Странное поведение переменных в пакетах, с большим количеством строк
    #39566263
Фотография dbms_photoshop
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ivan Rabashchenko,

А если включить
Код: plaintext
alter session set plsql_warnings = 'enable:all';
?
...
Рейтинг: 0 / 0
Странное поведение переменных в пакетах, с большим количеством строк
    #39566269
Ivan Rabashchenko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
К сожалению, только завтра смогу все проверить.
...
Рейтинг: 0 / 0
Странное поведение переменных в пакетах, с большим количеством строк
    #39566285
andreymx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ivan Rabashchenko,

еще можно попробовать дропнуть полностью пакет
и заново создать
...
Рейтинг: 0 / 0
Странное поведение переменных в пакетах, с большим количеством строк
    #39566289
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ivan RabashchenkoДля этого нужно изменить не только код генератора пакетов, но и всю парадигму системы, а это тьма кода, который работает поверх этих нелепых, неповоротливых, гигантских пакетов.
Как программист - не понимаю.

Если с размером specification проблем нет, а только с размером body, то никто не мешает точку входа в API оставить в одном пакете. Сделать пакет-прокси со старым именем, который просто будет вызывать функции из других пакетов. Код приложения, кроме генератора, менять не нужно

Единственная проблема чисто технического разделения - возможные связи между private (не вынесенные в спецификацию) функциями и глобальные переменные в пакете.

Лично я бы, первым делом, все глобальные переменные из пакета вынес в отдельный пакет (что бы на них всегда можно было ссылаться из всех генерированных пакетов), дальше бы разбирался, какие блоки функций можно отделить друг от друга. Сомневаюсь, что все 100 000 строк сгенерированного кода настолько сильно связаны друг с другом, что их не разделить.

Второе возможное решение, запрос в Oracle и фиксенье бага.

Поиск мелодии для бубна, который заставит обратно заработать систему у одного неудачливого заказчика.... это конечно хорошо, но как-то вызывает опасение. Если один раз свалилось на 100 000 строк кода, то кто может гарантировать, что в следующий раз не свалится на пакете в 101 000 строк кода и прошлогодняя мелодия и бубен поможет и в следующий раз?

IMHO & AFAIK
...
Рейтинг: 0 / 0
Странное поведение переменных в пакетах, с большим количеством строк
    #39566401
Ivan Rabashchenko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
xtender А эти неправильные значения в коде не встречаются случайно? Может тупо переполнение индекса идет
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
select count(*) from all_source
 where owner = 'XXXXXXX' 
   and type = 'PACKAGE BODY' 
   and name = 'SVC$23532PKG'
   and text like '%(429514,%'
   --
   130 --  429514 - некорректное значение, возвращаемое fIr$Tmp

select count(*) from all_source
 where owner = 'XXXXXXX' 
   and type = 'PACKAGE BODY' 
   and name = 'SVC$23532PKG'
   and text like '%26843545%'
   --
   3 -- это одна штатная fIr$Tmp + две, которые ввел по ходу обсуждения: fIr$Tmp2 + fIr$Tmp3



Есть такое. Чем мне (нам) этот факт может помочь?

MaximaXXLIvan Rabashchenko,

А можете попробовать с числом 268435455 и написать полученный результат?

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
function fIr$Tmp return number is
nRes number;
 begin        
    nRes :=  268435455;
    return nRes;
 end;
 
select SVC$23532PKG.fIR$Tmp as ver_0 from dual
-------
 VER_0
 429514



Ожидаемо, некорректный результат.
...
Рейтинг: 0 / 0
Странное поведение переменных в пакетах, с большим количеством строк
    #39566406
Ivan Rabashchenko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
andreymxIvan Rabashchenko,

еще можно попробовать дропнуть полностью пакет
и заново создать
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
drop package SVC$23532PKG;   
create or replace package SVC$23532PKG as...
create or replace package body SVC$23532PKG as...
    
select SVC$23532PKG.fIR$Tmp as ver_0 from dual
-------
 VER_0
 429514
...
Рейтинг: 0 / 0
Странное поведение переменных в пакетах, с большим количеством строк
    #39566424
andreymx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ivan Rabashchenko,

а так?
:)
Код: plsql
1.
2.
3.
4.
5.
6.
drop package SVC$23532PKG;   
--create or replace package SVC$23532PKG as...
--create or replace package body SVC$23532PKG as...
    
select SVC$23532PKG.fIR$Tmp as ver_0 from dual
???
...
Рейтинг: 0 / 0
Странное поведение переменных в пакетах, с большим количеством строк
    #39566429
Ivan Rabashchenko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
andreymxIvan Rabashchenko,

а так?
:)
Код: plsql
1.
2.
3.
4.
5.
6.
drop package SVC$23532PKG;   
--create or replace package SVC$23532PKG as...
--create or replace package body SVC$23532PKG as...
    
select SVC$23532PKG.fIR$Tmp as ver_0 from dual
???



Намекаете, что drop не отрабатывает?

Код: plsql
1.
2.
3.
4.
5.
drop package SVC$23532PKG;

select SVC$23532PKG.fIr$Tmp from dual

ORA-00904: "SVC$23532PKG"."FIR$TMP": invalid identifier
...
Рейтинг: 0 / 0
Странное поведение переменных в пакетах, с большим количеством строк
    #39566431
Фотография -2-
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Предполагаю, что проблема в количестве констант (нод). Возможно малая константа имеет в пкоде "непосредственную адресацию". Более 16 бит заносится в некую хеш-таблицу. При превышении количества 32767/65535 констант результат парса теряется. На выполнении из хеш-таблицы выбирается по индексу младших 15/16 бит.
...
Рейтинг: 0 / 0
Странное поведение переменных в пакетах, с большим количеством строк
    #39566438
Фотография -2-
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
set serveroutput on
declare
   c clob;
begin
   c := 'declare n number;begin'||chr(10);
   for i in 1..32768 loop
      c := c || ' n := ' || to_char(i+1000000) || ';' || chr(10);
   end loop;
   c := c || ' dbms_output.put_line(''n=''||n);' || chr(10);
   c := c || 'end;' || chr(10);
   dbms_output.put_line(substr(c, -53));
   execute immediate c;
end;
/

-- 32767/+1000000
 n := 1032767;
 dbms_output.put_line('n='||n);
end;

n=1032767

-- 32768/+1000000
 n := 1032768;
 dbms_output.put_line('n='||n);
end;

n=0

-- 32768/+0
 n := 32768;
 dbms_output.put_line('n='||n);
end;

n=32768
...
Рейтинг: 0 / 0
Странное поведение переменных в пакетах, с большим количеством строк
    #39566445
Ivan Rabashchenko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
dbms_photoshopIvan Rabashchenko,

А если включить
Код: plaintext
alter session set plsql_warnings = 'enable:all';
?

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
alter session set plsql_warnings = 'enable:all';
alter package SVC$23532PKG compile;

select  text, count(1) from dba_errors where name = 'SVC$23532PKG'  group by text
-----
PLW-06010: keyword "RESULT" used as a defined name	149
PLW-07203: parameter 'OP' may benefit from use of the NOCOPY compiler hint	1452
PLW-06002: Unreachable code	473
PLW-05018: unit SVC$23532PKG omitted optional AUTHID clause; default value DEFINER used	1
...
Рейтинг: 0 / 0
Странное поведение переменных в пакетах, с большим количеством строк
    #39566451
Ivan Rabashchenko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
dbms_photoshopРасплющенная принцессапропущено...
Это откуда? Смотри в доке plsql лимиты, там есть что посчитать. По объему parsed_code грозятся ошибкой pls-123.
И она даже возникает.
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
declare
   n           integer := 6551;
   spec_list   dbms_sql.varchar2a;
   body_list   dbms_sql.varchar2a;
   l_cursor    integer default dbms_sql.open_cursor;
   res         integer;
begin
   spec_list(1)                     := 'create or replace package pkg as';
   for i in 1 .. n
   loop
      spec_list(spec_list.count + 1):= 'function f' || i || ' return number;';
   end loop;
   spec_list(spec_list.count + 1)   := 'end;';
   dbms_sql.parse(l_cursor, spec_list, spec_list.first, spec_list.last, true, dbms_sql.native);
   res                              := dbms_sql.execute(l_cursor);

   body_list(1)                     := 'create or replace package body pkg as';
   for i in 1 .. n
   loop
      body_list(body_list.count + 1):= 'function f' || i || ' return number as
                                        begin return ' || i || '; end;';
   end loop;
   body_list(body_list.count + 1)   := 'end;';
   dbms_sql.parse(l_cursor, body_list, body_list.first, body_list.last, true, dbms_sql.native);
   res                              := dbms_sql.execute(l_cursor);
end;
/

PL/SQL procedure successfully completed.

select pkg.f6551 from dual;

     F6551
----------
      6551

declare
   n           integer := 6552;
   spec_list   dbms_sql.varchar2a;
   body_list   dbms_sql.varchar2a;
   l_cursor    integer default dbms_sql.open_cursor;
   res         integer;
begin
   spec_list(1)                     := 'create or replace package pkg as';
   for i in 1 .. n
   loop
      spec_list(spec_list.count + 1):= 'function f' || i || ' return number;';
   end loop;
   spec_list(spec_list.count + 1)   := 'end;';
   dbms_sql.parse(l_cursor, spec_list, spec_list.first, spec_list.last, true, dbms_sql.native);
   res                              := dbms_sql.execute(l_cursor);

   body_list(1)                     := 'create or replace package body pkg as';
   for i in 1 .. n
   loop
      body_list(body_list.count + 1):= 'function f' || i || ' return number as
                                        begin return ' || i || '; end;';
   end loop;
   body_list(body_list.count + 1)   := 'end;';
   dbms_sql.parse(l_cursor, body_list, body_list.first, body_list.last, true, dbms_sql.native);
   res                              := dbms_sql.execute(l_cursor);
end;
/

PL/SQL procedure successfully completed.

alter package pkg compile;

Warning: Package altered with compilation errors.

sho err
Errors for PACKAGE PKG:

LINE/COL ERROR
-------- -----------------------------------------------------------------
1/1      PLS-00123: program too large (Diana nodes)


Linux, 11.2.0.4

Указанный вам пример порождает PLS-00123 и у меня на разных платформах (Win\Linus\Solaris + 11.2.0.4\12.1.0.2)
...
Рейтинг: 0 / 0
Странное поведение переменных в пакетах, с большим количеством строк
    #39566454
Фотография -2-
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
declare n number;
begin
 n := 1000001;
 n := 1000002;
...
 n := 1032766;
 n := 1032767;
 dbms_output.put_line('32770='||32770);
 dbms_output.put_line('32769='||32769);
 dbms_output.put_line('32768='||32768);
 dbms_output.put_line('32767='||32767);
 dbms_output.put_line('1000001='||1000001);
 dbms_output.put_line('1032767='||1032767);
end;
/

32770=0
32769=1000001
32768=1000002
32767=32767
1000001=1000003
1032767=1000004
...
Рейтинг: 0 / 0
Странное поведение переменных в пакетах, с большим количеством строк
    #39566462
Ivan Rabashchenko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
-2-Предполагаю, что проблема в количестве констант (нод). Возможно малая константа имеет в пкоде "непосредственную адресацию". Более 16 бит заносится в некую хеш-таблицу. При превышении количества 32767/65535 констант результат парса теряется. На выполнении из хеш-таблицы выбирается по индексу младших 15/16 бит.

О, это уже горячо. Уважаемый, -2-, подскажите пжл документ, в котором указано такое ограничение.
...
Рейтинг: 0 / 0
Странное поведение переменных в пакетах, с большим количеством строк
    #39566466
Ivan Rabashchenko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
StaxIvan Rabashchenko,

на правах версии
переполняется "таблица констант"

если в конец пакета добавить еще одну ф-цию
fIr$Tmp2 с константой (напр 268435457),
они будут правильно работать?

ps
перемещая по телу пакета ф-цию, возможно можно определить когда перестает работать

.....
stax

Мне сразу дали намек, а его не понял...
...
Рейтинг: 0 / 0
Странное поведение переменных в пакетах, с большим количеством строк
    #39566482
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
-2-,

Имхо не хэш а переполнение индекса
...
Рейтинг: 0 / 0
Странное поведение переменных в пакетах, с большим количеством строк
    #39566487
Читаем доки
PL/SQL Program Limits
...
Рейтинг: 0 / 0
Странное поведение переменных в пакетах, с большим количеством строк
    #39566516
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
-2-Предполагаю, что проблема в количестве констант (нод). Возможно малая константа имеет в пкоде "непосредственную адресацию". Более 16 бит заносится в некую хеш-таблицу. При превышении количества 32767/65535 констант результат парса теряется. На выполнении из хеш-таблицы выбирается по индексу младших 15/16 бит.
Имхо как-то так должно быть:-2-Предполагаю, что проблема в количестве констант (нод). Возможно малая константа имеет в пкоде "непосредственную адресацию". Для оптимизации, константы Более 16 бит заносятся в некий массив, а вместо константы указывается ее индекс в этой таблице. На выполнении из-за переполнения из массива выбирается по индексу младших 15/16 бит.


PL/SQL Program LimitsЧитаем доки
PL/SQL Program Limits лимита на количество литералов там нет
...
Рейтинг: 0 / 0
25 сообщений из 77, страница 2 из 4
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Странное поведение переменных в пакетах, с большим количеством строк
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]