Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Oracle Новый топик    Ответить
 Пресловутая ошибка ORA-01792 и как это можно обойти (если можно)  [new]
EddySiebel
Member

Откуда:
Сообщений: 4
Добрый день!

Поискал на форуме по коду ошибки ORA-01792. Похожего не нашел. Во всех темах либо процедуры/функции, либо чуть чуть не в ту степь.

Есть задача, сделать сводный отчет (результат запроса) в разрезе групп и сотрудников по их "успеваемости" по записям, в сущностях ACTIONS и REQUESTS, созданным за последние 100 дней.

Ниже представлен код, который для удобства разнес по вью. В живом запросе все написано через WITH.
При выполнении результирующего запроса получаю ошибку:

ORA-01792: максимальное число столбцов в таблице или представлении - 1000
01792. 00000 - "maximum number of columns in a table or view is 1000"

Ошибка появляется при джойне вьюх в запрос. Если убрать джойны, то все по отдельности работает.
Порядок записей в таблицах ACTIONS, REQUESTS - по 200k, WORKER_GROUP - 800k, WORKER - 3k

CREATE OR REPLACE VIEW ACTION_V as
with ACTION as (select 
    FIELD1, FIELD2, TYPE, 
    case
        when PLAN_DATE >= sysdate and STATUS NOT IN ('Завершен','Отменен','Отказан') then 'IN_PROGRESS'
        when PLAN_DATE < sysdate and STATUS NOT IN ('Завершен','Отменен','Отказан') then 'OVERDUE'
        when PLAN_DATE <= sysdate and STATUS IN ('Завершен','Отменен','Отказан') then 'DONE'
    end as STATE
from 
    ACTIONS 
where
    START_DATE > sysdate - 100 and TYPE in ('Type1','Type2'))


select * from(
    select FIELD1, FIELD2, TYPE || '_' || STATE as TYPE_STATE, COUNT(*) as NUMS
    from ACTION
    group by 
        FIELD1, FIELD2, TYPE, STATE 
    order by 
        FIELD1, TYPE, STATE
)
pivot
(
    SUM(NUMS)
    for TYPE_STATE in ('Type1_IN_PROGRESS' as TYPE1_IN_PROGRESS,'Type1_OVERDUE' as TYPE1_OVERDUE,'Type1_DONE' as TYPE1_DONE,
		'Type2_IN_PROGRESS' as TYPE2_IN_PROGRESS,'Type2_OVERDUE' as TYPE2_OVERDUE,'Type2_DONE' as TYPE2_DONE)
)
;


CREATE OR REPLACE VIEW REQUEST_V as
with REQUEST as (select 
    FIELD1, FIELD2, TYPE, 
    case
        when PLAN_DATE >= sysdate and STATUS NOT IN ('Исполнен','Отменен') then 'IN_PROGRESS'
        when PLAN_DATE < sysdate and STATUS NOT IN ('Исполнен','Отменен') then 'OVERDUE'
        when PLAN_DATE <= sysdate and STATUS IN ('Исполнен','Отменен') then 'DONE'
    end as STATE
from 
    REQUESTS 
where
    START_DATE > sysdate - 100 and TYPE in ('Type1','Type2','Type3'))


select * from(
    select FIELD1, FIELD2, TYPE || '_' || STATE as TYPE_STATE, COUNT(*) as NUMS
    from REQUEST
    group by 
        FIELD1, FIELD2, TYPE, STATE 
    order by 
        FIELD1, TYPE, STATE
)
pivot
(
    SUM(NUMS)
    for TYPE_STATE in ('Type1_IN_PROGRESS' as TYPE1_IN_PROGRESS,'Type1_OVERDUE' as TYPE1_OVERDUE,'Type1_DONE' as TYPE1_DONE,
		'Type2_IN_PROGRESS' as TYPE2_IN_PROGRESS,'Type2_OVERDUE' as TYPE2_OVERDUE,'Type2_DONE' as TYPE2_DONE
		'Type3_IN_PROGRESS' as TYPE3_IN_PROGRESS,'Type3_OVERDUE' as TYPE3_OVERDUE,'Type3_DONE' as TYPE3_DONE)
)
;

select tt.*, act.*, req.* from
    (select
        wg.GRNAME, w.FIO, w.FIELD1, wg.FIELD2
    from 
	WORKER_GROUP wg
	join WORKER w ON w.ID=wg.WORKER_ID
	join AREA ar ON ar.ID=wg.AREA_ID
    where 
        ROLE='Manager'
    group by 
		FNAME, FIO, FIELD1, FIELD2) tt
left outer join ACTION_V act ON act.FIELD1=tt.FIELD1 and act.FIELD2=tt.FIELD2
left outer join REQUEST_V req ON req.FIELD1=tt.FIELD1 and req.FIELD2=tt.FIELD2
;


покопавшись на металинке нашел Doc ID 1951689.1, где сказано следующее

Metalink
SOLUTION
The workaround is to set "_fix_control"='17376322:OFF'
SQL> alter session set "_fix_control"='17376322:OFF';
or at system level :
SQL> alter system set "_fix_control"='17376322:OFF';
OR
Apply Patch 19509982 if available for your DBVersion and Platform


Версия рабочей базы, как раз та, что указана в статье:
Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
PL/SQL Release 12.1.0.2.0 - Production

Теперь вопросы:
1. Можно ли это сделать на SQL (без процедур и функций) каким либо еще образом, чтобы не выстреливала данная ошибка?
2. Если отключить проверку, могут ли быть какие либо негативные последствия?

К сожалению, я не являюсь ДБА, поэтому такие вопросы.
11 ноя 21, 08:21    [22394512]     Ответить | Цитировать Сообщить модератору
 Re: Пресловутая ошибка ORA-01792 и как это можно обойти (если можно)  [new]
PuM256
Member

Откуда:
Сообщений: 168
EddySiebel
Добрый день!
Теперь вопросы:
1. Можно ли это сделать на SQL (без процедур и функций) каким либо еще образом, чтобы не выстреливала данная ошибка?

Можно добавить в запрос хинт /*+ OPT_PARAM('_fix_control' '17376322:OFF') */
EddySiebel
Добрый день!
2. Если отключить проверку, могут ли быть какие либо негативные последствия?

Сталкивался с этим багом. Мне 17376322:OFF помог без негативных последствий. Но всё надо тестировать, конечно.
11 ноя 21, 10:47    [22394555]     Ответить | Цитировать Сообщить модератору
 Re: Пресловутая ошибка ORA-01792 и как это можно обойти (если можно)  [new]
EddySiebel
Member

Откуда:
Сообщений: 4
PuM256,

Спасибо за рекомендацию!
для понимания:
При таком указании эта директива будет выполняться только для этого запроса в момент вызова?
Или она будет установлена в сессии запуска этого запроса?


негативные последствия в уже, скажем так, существующих процессах. Проверить то это у меня никак не получится. А админы сказали, можем установить указанный в саппорте патч под вашу ответственность))) грусть печаль
11 ноя 21, 11:15    [22394565]     Ответить | Цитировать Сообщить модератору
 Re: Пресловутая ошибка ORA-01792 и как это можно обойти (если можно)  [new]
EddySiebel
Member

Откуда:
Сообщений: 4
Попробовал подставить хинт.
Выполнил запрос с хинтом он отработал. Убрал хинт, перестал работать.

Вывод: для текущего запроса. Если не прав, прошу поправить)
11 ноя 21, 11:25    [22394572]     Ответить | Цитировать Сообщить модератору
 Re: Пресловутая ошибка ORA-01792 и как это можно обойти (если можно)  [new]
PuM256
Member

Откуда:
Сообщений: 168
EddySiebel,

Хинт сработает только для этого запроса.
Alter session - для всех запросов, выполняемых в текущей сессий
Alter system - глобально во всей базе
Патч - тоже, естественно, глобально
11 ноя 21, 11:31    [22394573]     Ответить | Цитировать Сообщить модератору
 Re: Пресловутая ошибка ORA-01792 и как это можно обойти (если можно)  [new]
EddySiebel
Member

Откуда:
Сообщений: 4
PuM256,

Спасибо!

Проблема решена.
11 ноя 21, 11:59    [22394582]     Ответить | Цитировать Сообщить модератору
Все форумы / Oracle Ответить