使用oracle plsql触发器计算生日年龄并在表中插入年龄

前端之家收集整理的这篇文章主要介绍了使用oracle plsql触发器计算生日年龄并在表中插入年龄前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一张桌子
dates
(dob date,age number(4)
);

我将插入一个出生日期,触发器将计算年龄并在年龄字段中插入该年龄.

CREATE OR REPLACE PROCEDURE getage IS 
ndob date;
nage number(10);
BEGIN
select dob into ndob from dates; 
select (sysdate-to_date(ndob))/365 into nage from dual;
update dates set age=nage;
END;
/
SHOW ERRORS;

这个过程工作正常,但只有一行,我需要触发所有行,但如果我从触发器调用它,则会发生错误.

CREATE OR REPLACE TRIGGER agec after INSERT OR UPDATE ON dates
FOR EACH ROW
BEGIN
getage;
END; 
/

please help…i really need this…

不,你没有.我不确定你会注意;并且没有理由你应该:-)但是:

不要在数据库中存储年龄.你绝对保证偶尔会出错.每个人每年的年龄都会发生变化,但是,对于某些人来说,每天都会发生变化.这反过来意味着您需要每天运行批处理作业并更新年龄.如果这个失败,或者不是非常严格并且运行两次,那你就麻烦了.

您应该随时根据需要计算年龄.这是一个相当简单的查询,从长远来看可以为您节省很多痛苦.

select floor(months_between(sysdate,<dob>)/12) from dual

我已经设置了一个SQL Fiddle来演示

现在,实际回答你的问题

this procedure works fine but for only one row,but for all the rows
i need trigger but if i call it from a trigger then the error
occurs…

你没有提到错误,请在将来这样做,因为它非常有帮助,但我怀疑你得到了

ORA-04091: table string.string is mutating,trigger/function may not
see it

这是因为您的过程正在查询正在更新的表. Oracle不允许这样做以维护数据的读一致视图.避免这种情况的方法是不查询表,您不需要这样做.将您的程序更改为在出生日期返回正确结果的函数

function get_age (pDOB date) return number is
   /* Return the the number of full years between 
      the date given and sysdate.
      */    
begin    
   return floor(months_between(sysdate,pDOB)/12);    
end;

再次注意我使用的是months_between()功能,因为并非所有年份都有365天.

在触发器中,然后将值直接分配给列.

CREATE OR REPLACE TRIGGER agec before INSERT OR UPDATE ON dates
FOR EACH ROW
BEGIN
   :new.age := get_age(:new.dob);
END;

:new.< column>语法是对< column>的引用正在更新.在这种情况下:new.age是将放入表中的实际值.

这意味着您的表将自动更新,即the point of a DML trigger.

正如你所看到的那样,功能根本没什么意义;你的触发器可以成为

CREATE OR REPLACE TRIGGER agec before INSERT OR UPDATE ON dates
FOR EACH ROW
BEGIN
   :new.age := floor(months_between(sysdate,:new,DOB)/12);
END;

但是,话虽如此,如果您打算在数据库的其他地方使用此功能,请将其保持独立.在这样的函数中保留在多个位置使用的代码是一种很好的做法,因此它总是以相同的方式使用.它还确保每当有人计算年龄时,他们都会正确地做到这一点.

稍微放一点,你确定你想让人们成为9,999岁吗?或0.000000000001998 (proof)Numeric precision基于有效数字;这(根据Oracle)仅为非零数字.你很容易被这个抓住.数据库的要点是将可能的输入值限制为仅有效的输入值.我认真考虑将您的年龄列声明为数字(3,0)以确保仅包含“可能”值.

猜你在找的Oracle相关文章