我使用以下代码在 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;
虚拟列工作正常,它确实填充了我想要在虚拟列中实现的目标。但是当我使用虚拟列的表创建视图时出现了问题;视图的数量需要大量时间(最多 5 分钟)。在这里,我想提一下,如果我不使用该功能(即电子邮件的空列),该视图将完全正常工作。查看代码如下
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;
我推测的是,当我创建一个虚拟列时,oracle 强行要求我将数据类型长度保持在 4000,从而使其太大或太重而无法填充。我应该怎么做才能填充视图。我需要一个虚拟列,因为应用程序没有输入电子邮件。需要帮助。
我不认为这是列的大小(顺便说一句:不要“假定”,测试)。
我敢打赌,结果中的每一行都会一遍又一遍地调用该函数。因此,对于结果中的每一行,您都会在人员表上进行两次(!)选择。编辑:我上面的说法是错误的。虚拟列的函数仅在其所基于的列更新时调用。
您可以通过在函数中仅执行一次 SELECT 来稍微改进一下:
但我建议简单地将逻辑放入视图中并在视图中构造电子邮件字符串:
这样就不需要额外的选择,它应该运行得很好。