我在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;
虚拟列工作正常,它确实填充了我想要在虚拟列中实现的目标。但是当我使用虚拟列的表创建 View 时出现了问题;性能变得非常糟糕( View 的填充)。在这里,我想提一下,如果我不使用该功能(即电子邮件的空列),该 View 工作得很好。
查看代码如下
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,从而使其太大或太重而无法填充。我应该怎么做才能填充 View 。我需要一个虚拟列,因为应用程序没有输入电子邮件。
需要帮助。
最佳答案
我不认为这是列的大小(顺便说一句:不要“假设”,测试)。
我敢打赌,结果中的每一行都会一遍又一遍地调用该函数。因此,对于结果中的每一行,您在 person 表上进行两次(!)选择。
编辑:我上面的说法是错误的。虚拟列的函数仅在其所基于的列更新时调用。
您可以通过在您的函数中仅执行一次 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_;
但我建议简单地将逻辑放入 View 中并在 View 中构造电子邮件字符串:
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;
这样就不需要额外的选择,它应该可以正常运行。
关于sql - 虚拟列 - 在 View 中使用它 (Oracle),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8457032/