CftClub.ru
Клуб специалистов ЦФТ-Банк

Непонятное поведение системы. ORA-20100

 
Ответить на тему    Клуб специалистов ЦФТ-Банк (IBSO) -> Уроки ЦФТ-Банк для начинающих
Предыдущая тема :: Следующая тема  
Автор Сообщение
MVZ
Участник со стажем


Вступление в Клуб: 14.03.2023
СообщениеЧт Мар 16, 2023 01:26   Непонятное поведение системы. ORA-20100 Ответить с цитатой
Полезность: Нет оценки
Коллеги, добрый день.

Прошу вашей помощи, для новичка.

Немного о себе. Недавно устроился программистом в финансовую компанию, в которой используется CFT. Есть тестовая задача без прикладной нагрузки. В процессе реализации задачи, я наткнулся на непонятное мне поведение системы, причем не CFT а ORACLE. Прошу вашей помощи в понимании проблеммы.

Код ошибки:
Код:
ORA-20100: ORA-00904: "A1"."ID": íåäîïóñòèìûé èäåíòèôèêàòîð
ORA-00904: "A1"."ID": íåäîïóñòèìûé èäåíòèôèêàòîð
ORA-06512: íà  "SYS.DBMS_SQL", line 1134
ORA-06512: íà  "SYS.DBMS_SQL", line 1134
ORA-06512: íà  "IBS.DATA_VIEWS", line 2951
ORA-06512: íà  "IBS.MESSAGE", line 206
ORA-06512: íà  "IBS.DATA_VIEWS", line 3016
ORA-06512: íà  line 1
begin  IBS.Data_Views.Create_Vw_Crit(:crit_id, false); end;


Код с интерпретатора
Код:
/* CREATE OR REPLACE VIEW VW_CRIT_KMB AS */
SELECT
A1.Id ID, a2.CLASS_ID Class_Id,
a2.C_NAME C_1,
b1.C_NUMB C_2,
c1.C_IMP_STR C_3,
(
         select  COUNT(1) A$1
         from Z#VZ_CARDS h1 join Z#IP_CARDS h2 on h1.id=h2.id
         where h2.C_CLIENT = a1.ID and h1.STATE_ID not in ('Çàêðûòà','Íà çàêðûòèè')
      ) C_4,
(
         select  COUNT(1) A$1
         from Z#DEPOSIT_PRIV i1 join Z#DEPN i2 on i1.id=i2.id join Z#PRODUCT i3 on i1.id=i3.id
         where i2.C_CLIENT = a1.ID and i3.C_DATE_CLOSE is NULL
      ) C_5,
(
         select  COUNT(1) A$1
         from Z#PR_CRED j1 left join Z#KIND_CREDITS j2 on j1.C_KIND_CREDIT=j2.id join Z#PRODUCT j3 on j1.id=j3.id
         where j1.C_CLIENT = a1.ID and j2.C_IS_FOR_CRED_CARD = '1' and j3.C_DATE_CLOSE is NULL
      ) C_6
      from (Z#CL_PRIV a1 join Z#CLIENT a2 on a1.id=a2.id) left join Z#CONTACTS b1 on b1.COLLECTION_ID = a2.C_CONTACTS left join Z#PERSONAL_ADDRESS c1 on c1.COLLECTION_ID = a2.C_ADDRESSES left join (
         select  e1.C_ID C_ID, e1.C_DATE_BEGINING C_DATE_BEGINING, e1.C_DEPART C_DEPART, e1.C_CLIENT C_CLIENT
         from (
            select  f1.ID C_ID, f2.C_DATE_BEGINING C_DATE_BEGINING, f3.C_CODE C_DEPART, f1.C_CLIENT C_CLIENT
            from Z#DEPN f1 join Z#PRODUCT f2 on f1.id=f2.id left join Z#DEPART f3 on f2.C_DEPART=f3.id
            where f1.C_CLIENT = a1.ID
            union all
            select  g1.ID C_ID, g2.C_DATE_BEGINING C_DATE_BEGINING, g3.C_CODE C_DEPART, g1.C_CLIENT C_CLIENT
            from Z#PR_CRED g1 join Z#PRODUCT g2 on g1.id=g2.id left join Z#DEPART g3 on g1.C_DEPART=g3.id
            where g1.C_CLIENT = a1.ID
         ) e1
         order by e1.C_DATE_BEGINING
         fetch first 1 rows only
      ) d1 on d1.C_CLIENT = a1.ID
      where b1.COLLECTION_ID = a2.C_CONTACTS and (b1.C_MAIN = '1') and b1.C_TYPE = 1919465 and c1.COLLECTION_ID = a2.C_ADDRESSES and c1.C_TYPE = 2047916
 AND
  ( SYS_CONTEXT('IBS_SYSTEM','ADMIN')='1' OR EXISTS
    (
      SELECT 1 FROM Criteria_Rights M_R, Subj_Equal SE
       WHERE M_R.Obj_Id ='6991883375' AND M_R.Class_Id='MZ_TEST_DOC'
         AND M_R.Subj_Id=SE.Equal_Id AND SE.Subj_Id=SYS_CONTEXT('IBS_SYSTEM','USER')
    )
  )

 AND SYS_CONTEXT('IBS_OPTIONS','6991883375') is null
 AND SYS_CONTEXT('USERENV', 'CLIENT_IDENTIFIER') is null


Код Представления
Код:
TYPE main IS
   SELECT person(   
      --ui.c_client%id : id,
      person.[NAME]                                          :   C_NAME,            -- Полное наименование физ. лица                                                         
      conta.[NUMB]                                          :   C_CELLPHONE,      -- Телефон мобильный
      addr.[imp_str]                                          :   C_ADDRESS,         -- Получить адрес регистрации
      
      -- #4. Дебетовые карты
      (SELECT rec(COUNT(1)) IN ::[VZ_CARDS] ALL
         WHERE rec.[CLIENT] = person%id          
            AND rec%state NOT IN ( 'Закрыта', 'На закрытии' )            
         )                                                :   C_DEBT_CARDS_COUNT,   -- Количество не закрытых дебетовых карт
         
      -- #5. Депозиты
      (SELECT rec(COUNT(1)) IN ::[DEPOSIT_PRIV] ALL
         WHERE rec.[CLIENT] = person%id          
            AND rec.[DATE_CLOSE] IS NULL    
      )                                                   :   C_DEPOSIT_COUNT,   -- Количество не закрытых депозитов
      
      --#6. Кредитные карты
      (SELECT rec(COUNT(1)) IN ::[PR_CRED] ALL
         WHERE rec.[CLIENT] = person%id
            AND rec.[KIND_CREDIT]->(TRUE)[IS_FOR_CRED_CARD] = '1'
            AND rec.[DATE_CLOSE] IS NULL          
               
      )                                                   :   C_CRED_CARDS_COUNT--,   -- Количество не закрытых кредитных карт
      --#7. Подразделение
      --dt.C_DEPART                                             :   C_DEPARTMENT      -- Подразделение
      
   )
   IN ::[CL_PRIV]
   
   LEFT JOIN ( ::[CONTACTS] ALL : conta) ON conta%collection = person.[CONTACTS]
   LEFT JOIN ( ::[PERSONAL_ADDRESS] ALL : addr) ON addr%collection = person.[ADDRESSES]   
   
            
   -- Проблемный код. Если ставим условие WHERE prod.CLIENT=person%id, то компиляция ORACLE  не проходит
   LEFT JOIN ( SELECT  dt( dt.[C_ID]           : C_ID,
                     dt.[C_DATE_BEGINING] : C_DATE_BEGINING,
                     dt.[C_DEPART]        : C_DEPART,
                     dt.[C_CLIENT]        : C_CLIENT
                  
                  ) IN
                     ( SELECT prod(prod%id           : C_ID,
                                 prod.DATE_BEGINING : C_DATE_BEGINING,
                                 prod.DEPART.CODE     : C_DEPART,
                                 prod.CLIENT        : C_CLIENT
                            ) IN ::[DEPN] ALL WHERE prod.CLIENT=person%id -- prod.CLIENT=71312958
                           
                       UNION ALL
                      
                       SELECT prod(prod%id           : C_ID,
                                prod.DATE_BEGINING : C_DATE_BEGINING,
                                 prod.DEPART.CODE     : C_DEPART,
                                 prod.CLIENT        : C_CLIENT
                            ) IN ::[PR_CRED] ALL WHERE prod.CLIENT=person%id -- prod.CLIENT=71312958
                      
                  ) ORDER BY dt.[C_DATE_BEGINING] FETCH 1
                  
            ) ON dt.C_CLIENT = person%id   
            
   
   WHERE conta%collection = person.[CONTACTS]
            AND conta.[MAIN]
            AND conta.[TYPE]    = ::[COMUNICATION]([CODE] ='PHONE')            
            AND addr%collection = person.[ADDRESSES]
            AND addr.[TYPE]    = ::[ADDRESS_TYPE]([KOD] ='REGISTRATION')   
            
;


Суть вопроса
Помогите пожалуйста понять почему в последнем JOIN условие WHERE prod.CLIENT=person%id провоцирует исключение ORACLE. Мне кажется что данный код является достаточно эффективным, но почему то интерпретатор CFT компилирует его с исключением для ORACLE.

Суть прикладной логики вытащить наиболее ранний банковский продукт выданный клиенту.

Заранее благодарен,
С Уважением,
Максим.[/u]
Volod
Эксперт


Вступление в Клуб: 19.09.2007
СообщениеЧт Мар 16, 2023 17:51    Ответить с цитатой
Полезность: Нет оценки
ИМХО, проблема связана с подселектом, попробуйте тоже самое повторить без подселекта, т.е это
LEFT JOIN ( SELECT dt( dt.[C_ID] : C_ID,
dt.[C_DATE_BEGINING] : C_DATE_BEGINING,
dt.[C_DEPART] : C_DEPART,
dt.[C_CLIENT] : C_CLIENT
сразу IN ::[DEPN]
MVZ
Участник со стажем


Вступление в Клуб: 14.03.2023
СообщениеПт Мар 17, 2023 10:07    Ответить с цитатой
Полезность: Нет оценки
Добрый день,

да так работает, но нужно именно с подселектом. Непонятно почему интерпретатор компилирует не рабочий для оракла код...
Volod
Эксперт


Вступление в Клуб: 19.09.2007
СообщениеПт Мар 17, 2023 16:31    Ответить с цитатой
Полезность: Нет оценки
Потому что Oracle так устроен.
MVZ
Участник со стажем


Вступление в Клуб: 14.03.2023
СообщениеСб Мар 18, 2023 07:20    Ответить с цитатой
Полезность: Нет оценки
Volod пишет:
Потому что Oracle так устроен.

Все понятно Smile
Эмиралька
Эксперт


Вступление в Клуб: 09.11.2015
СообщениеВт Мар 21, 2023 11:49   Re: Непонятное поведение системы. ORA-20100 Ответить с цитатой
Полезность: Нет оценки
MVZ пишет:
Код ошибки:
Код:
ORA-20100: ORA-00904: "A1"."ID": íåäîïóñòèìûé èäåíòèôèêàòîð
ORA-00904: "A1"."ID": íåäîïóñòèìûé èäåíòèôèêàòîð


Прежде всего, непонятно, чего вы хотите Smile
CSmaster
Участник со стажем


Вступление в Клуб: 24.09.2021
СообщениеВт Мар 21, 2023 13:35    Ответить с цитатой
Полезность: 1
MVZ пишет:
Добрый день,

да так работает, но нужно именно с подселектом. Непонятно почему интерпретатор компилирует не рабочий для оракла код...

Не каждый человек может написать работающий код, интерпретатор и подавно Smile
Почему как вы хотите и не работает, в данном случае секрета нет, если знать в какой последовательности Oracle анализирует запрос и генерирует план выполнения. Другим СУБД тоже присуще аналогичное поведение, но со своими нюансами. Рекомендую почитать, какие выражения при разборе анализируется вначале, какие в конце (from, group by, order by, аналитические функции и тд).
Показать сообщения:   
Ответить на тему    Клуб специалистов ЦФТ-Банк (IBSO) -> Уроки ЦФТ-Банк для начинающих Часовой пояс: GMT + 3
Страница 1 из 1

 
Перейти:  
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Рейтинг@Mail.ru