powered by simpleCommunicator - 2.0.52     © 2025 Programmizd 02
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Проблема с константой типа CHAR в Oracle 12с
12 сообщений из 12, страница 1 из 1
Проблема с константой типа CHAR в Oracle 12с
    #39944717
Artem_7
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый день.

Провели миграцию с Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bi на Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production . Часть пакетов на схеме стало инвалидными. Ошибка такая:

Код: plsql
1.
PLS-00801: internal error [*** ASSERT at file pdy3.c, line 1930; Layout Mismatch - 2 < 16; PACKAGE_SCHEMA__B__63083[4363, 1]] (ERROR 801)



Стал разбираться, нашел, что проблема в nullable константе типа CHAR(1). Привожу пример кода для воспроизведения:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
DECLARE
  c_NULL  CONSTANT CHAR(1) := NULL;   
  
  v_bool  BOOLEAN;
  ------------------------------------------
  FUNCTION is_null
  (
    i_value      IN VARCHAR2
  )
  RETURN BOOLEAN
  AS
  BEGIN
    RETURN (i_value IS NULL);
  END is_null;    
  ------------------------------------------
BEGIN
  v_bool := is_null( c_NULL);  
END;  



На 10g выполняется, на 12с ломается. Причем, если поменять тип c_NULL с CHAR(1) на VARCHAR2(1) , то все будет работать на обеих версиях. Если убрать CONSTANT из определения c_NULL, то тоже все будет работать на обеих версиях.

Вопрос: почему так? Это баг 12с или какое-то дополнительное новое ограничение?
...
Рейтинг: 0 / 0
Проблема с константой типа CHAR в Oracle 12с
    #39944723
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Artem_7
Вопрос: почему так?
Разработчики в здравом уме не используют странный тип CHAR вообще. И поэтому даже не знают о всём том многообразии сексуальных проблем с ним.
Но у тебе даже есть выбор - переходи на 18, там небезопасный секс так строго не наказывается.
...
Рейтинг: 0 / 0
Проблема с константой типа CHAR в Oracle 12с
    #39944726
Artem_7
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Elic, это синтетический код для воспроизведения ошибки. В реальном коде константа имеет тип TABLE.COLUMN%TYPE. В таблице колонка с типом CHAR(1), используется для хранения значений Y/N. И да, все колонки для хранения булевых значений в схеме имеют тип CHAR(1).
Как пофиксить ошибку - тоже понятно. Самое простое добавить в пакет SUBTYPE t_YES_NO IS VARCHAR2(1) и перейти на него.
Но если ошибка вызвана багом, то лучше ее лечить патчем Oracle, а не повсеместной правкой кода.
...
Рейтинг: 0 / 0
Проблема с константой типа CHAR в Oracle 12с
    #39944730
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Artem_7
Но если ошибка вызвана багом, то лучше ее лечить патчем Oracle, а не повсеместной правкой кода.
Зависит от мировоззрения.
Можно каждый раз одевать высокие ботфорты, чтобы ходить по дерьму, срезая путь через ферму.
А можно ходить по проторенным дорогам вокруг ферм и даже в тапочках.
...
Рейтинг: 0 / 0
Проблема с константой типа CHAR в Oracle 12с
    #39944731
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Artem_7
В реальном коде константа имеет тип TABLE.COLUMN%TYPE.
, а не повсеместной правкой кода.
Хоть иногда alter table modify может быть нетривиальным, но это достаточно сделать один раз. И это вовсе не "правка кода".
...
Рейтинг: 0 / 0
Проблема с константой типа CHAR в Oracle 12с
    #39944736
Artem_7
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Может, кому пригодится. Нашли Bug 24924667


Bug 24924667 : PLS-00801 LAYOUT MISMATCH ERROR WHILE COMPILING PLSQL WITH CONSTANT VARIABLECompiling PLSQL code which has constant variable with NULL assigned to it 
fails with below error. That too when this constant is passed to oracle 
standard packages.
 
PLS-801: internal error [*** ASSERT at file pdy3.c, line 1922;
Layout Mismatch - 2 < 13; TEST_CONST_CHAR__SCOTT__B__20460[16,4]]
 
Workaround :
1) Instead of assigning NULL, assign '' to constant variable.
2) Prefix "test_var" with some other values (ie) ''||test_var.
...
Рейтинг: 0 / 0
Проблема с константой типа CHAR в Oracle 12с
    #39944744
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Bug 24924667 : PLS-00801 LAYOUT MISMATCH ERROR WHILE COMPILING PLSQL WITH CONSTANT VARIABLE
Workaround :
1) Instead of assigning NULL, assign '' to constant variable.
2) Prefix "test_var" with some other values (ie) ''||test_var.
Это да. Можно обуваться в ботфорты малинового или голубого цвета. Чтобы ходить по куче дерьма.
С точки зрения потребителя, я скажу, что вы создаёте добавленную стоимость оракла, не создавая собственной добавленной стоимости. Кому от этого хорошо?
...
Рейтинг: 0 / 0
Проблема с константой типа CHAR в Oracle 12с
    #39944758
Artem_7
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
В топике описан баг обратной совместимости. Oracle баг признал и пофиксил.
На всякий случай предупреждаю тех, кто наступит на данную ошибку. Workaround-ы, описанные в Bug 24924667, чинят компиляцию кода, но могут сломать бизнес-логику. Пользоваться ими не рекомендую. Причина проста:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
DECLARE
  v_value     CHAR(1);

BEGIN
  v_value := NULL;  -- значение по факту NULL
  dbms_output.put_line(CASE WHEN v_value IS NULL THEN 'value is NULL' ELSE 'value is not NULL' END);
  
  v_value := ''; -- значение по факту "пробел"
  dbms_output.put_line(CASE WHEN v_value IS NULL THEN 'value is NULL' ELSE 'value is not NULL' END);
END;  



Поэтому, либо ставим фикс от Oracle, либо меняем тип константы/переменной
...
Рейтинг: 0 / 0
Проблема с константой типа CHAR в Oracle 12с
    #39944760
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Artem_7
Может, кому пригодится. Нашли Bug 24924667


Bug 24924667 : PLS-00801 LAYOUT MISMATCH ERROR WHILE COMPILING PLSQL WITH CONSTANT VARIABLECompiling PLSQL code which has constant variable with NULL assigned to it 
fails with below error. That too when this constant is passed to oracle 
standard packages.
 
PLS-801: internal error [*** ASSERT at file pdy3.c, line 1922;
Layout Mismatch - 2 < 13; TEST_CONST_CHAR__SCOTT__B__20460[16,4]]
 
Workaround :
1) Instead of assigning NULL, assign '' to constant variable.
2) Prefix "test_var" with some other values (ie) ''||test_var.


совет конешно интересный Instead of assigning NULL, assign '' to constant variable.
логика ж поменяется, тем более для константы

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
SQL>  ed
Wrote file afiedt.buf

  1  declare
  2   c_null CONSTANT CHAR(1) := null;
  3   c_char CONSTANT CHAR(1) := '';
  4  begin
  5   if c_null is null then
  6    dbms_output.put_line('c_null -Null');
  7   else
  8    dbms_output.put_line('c_null -else');
  9   end if;
 10   if c_char is null then
 11    dbms_output.put_line('c_char -Null');
 12   else
 13    dbms_output.put_line('c_char -else');
 14   end if;
 15* end;
SQL> /
c_null -Null
c_char -else

PL/SQL procedure successfully completed.



....
stax
...
Рейтинг: 0 / 0
Проблема с константой типа CHAR в Oracle 12с
    #39944764
Фотография -2-
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Artem_7
Может, кому пригодится.
Вряд ли кто-то еще затеет "апгрейд" на глюковерсию x.x.0.1 трехлетней давности, когда ее саппорт закончится через полгода.
...
Рейтинг: 0 / 0
Проблема с константой типа CHAR в Oracle 12с
    #39944781
Вячеслав Любомудров
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ставим фикс
Там есть еще подобный баг с >8 параметрами в GREATEST (и других функциях) в PL/SQL
...
Рейтинг: 0 / 0
Проблема с константой типа CHAR в Oracle 12с
    #39945102
Фотография Кобанчег
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Artem_7,

Лучше когда не работает чем когда работает, но неправильно.
Код: 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.
SQL> alter session set plsql_optimize_level = 3;

Session altered.

SQL> declare
  2    c_null constant char(1) := null;
  3    ------------------------------------------
  4    function is_null(i_value in varchar2) return int as
  5    begin
  6      return case when i_value is null then 0 else 1 end;
  7    end is_null;
  8    ------------------------------------------
  9  begin
 10    dbms_output.put_line(is_null(c_null));
 11  end;
 12  /
1

PL/SQL procedure successfully completed.

SQL> declare
  2    c_null /*constant*/ char(1) := null;
  3    ------------------------------------------
  4    function is_null(i_value in varchar2) return int as
  5    begin
  6      return case when i_value is null then 0 else 1 end;
  7    end is_null;
  8    ------------------------------------------
  9  begin
 10    dbms_output.put_line(is_null(c_null));
 11  end;
 12  /
0

PL/SQL procedure successfully completed.


В первом случае PLS-00801 не возникло благодаря тому, что plsql_optimize_level = 3 форсирует inlining,
...
Рейтинг: 0 / 0
12 сообщений из 12, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Проблема с константой типа CHAR в Oracle 12с
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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