Виртуальный столбец - используя его в представлении (Oracle) - PullRequest
2 голосов
/ 10 декабря 2011

Я создал виртуальный столбец в Oracle, используя следующий код.

CREATE OR REPLACE function email_address (ID_ varchar2)
return varchar2
deterministic
as

lname varchar2 (256);
snumber varchar2 (256);
 email varchar2 (256);
    BEGIN
    select substr( p.name, instr( p.name, ' ', -1 ) + 1 ) into lname
    from person p where p.id = id_;

    SELECT regexp_replace(p.service_no, '[^0-9]*', '') into snumber
    FROM person p where p.ID = id_;

  email:= snumber||lname||'@met.af';

return email;
end email_address;


Виртуальный столбец работает нормально, и он заполняет то, что я хочу получить в виртуальном столбце. Но проблема возникает, когда я делаю представление, используя таблицу виртуального столбца; производительность становится действительно плохой (популяция зрения). Здесь я хотел бы отметить, что представление работает отлично, если я не использую функцию (т.е. пустой столбец электронной почты). Код для просмотра как под

select  distinct
    person.SERVICE_NO as Service_No,
    person.CNIC_NO as CNIC, person.NAME as NAME ,
    card.CPLC_SERIAL_NO as Card_Number,
    child_dc.NAME as Child_DC,
    root_dc.NAME as Root_DC, person.OU as OU,
    person.EMAIL as Email
from

 person_card inner join person
 on person_card.PERSON_ID = person.ID
 inner join card
 on person_card.CARD_ID = card.ID
    left outer join child_dc
 on person.CHILD_DC_ID = child_dc.ID
    left outer join root_dc
 on child_dc.ID = root_dc.ID; 


Я предполагаю, что когда я создаю виртуальную колонку, оракул насильно просит меня сохранить длину типа данных до 4000, то есть сделать его слишком большим или тяжелым для заполнения. Что я должен сделать, чтобы сделать представление заполненным. Мне нужно иметь виртуальный столбец, так как приложение не вводит электронную почту. Требуется помощь.

1 Ответ

7 голосов
/ 10 декабря 2011

Я не думаю, что это размер столбца (кстати: не " предположить ", тест).

Могу поспорить, что функция вызывается снова и снова для каждой строки результата.Таким образом, для каждой строки в результате вы делаете два (!) Выбора в таблице персонажа.

Редактировать : Я был не прав с приведенным выше утверждением.Функция для виртуального столбца вызывается только при обновлении столбца, на котором она основана.

Вы можете немного улучшить это, сделав только один SELECT в вашей функции:

select substr( p.name, instr( p.name, ' ', -1 ) + 1 ), 
       regexp_replace(p.service_no, '[^0-9]*', '')
   into lname, snumber
from person p where p.id = id_;

НоЯ бы порекомендовал просто поместить эту логику в представление и создать строку электронной почты внутри представления:

select  distinct
        person.SERVICE_NO as Service_No,
        person.CNIC_NO as CNIC, person.NAME as NAME ,
        card.CPLC_SERIAL_NO as Card_Number,
        child_dc.NAME as Child_DC,
        root_dc.NAME as Root_DC, person.OU as OU,
        regexp_replace(p.service_no, '[^0-9]*', '')||substr( p.name, instr( p.name, ' ', -1 ) + 1 )||'@met.af' as email
from person_card 
inner join person
 on person_card.PERSON_ID = person.ID
inner join card
 on person_card.CARD_ID = card.ID
    left outer join child_dc
 on person.CHILD_DC_ID = child_dc.ID
    left outer join root_dc
 on child_dc.ID = root_dc.ID; 

Таким образом, дополнительный выбор не требуется, и он должен работать просто отлично.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...