Subject | Updateable View's trigger oddity |
---|---|
Author | Bambang P |
Post date | 2005-09-03T05:12:47Z |
I have a simple table (DURATION) which has a field to store duration in minutes,
let us call it DURATION_MINUTES
To make it more "user friendly" then I make a view which split the
DURATION_MINUTES in 2 integer fields: DUR_HOUR, DUR_MIN by simple math:
Hour = Total_Minutes/60
Minute = Total_Minutes - ((Total_Minutes/60)*60)
Note: integer division results in integer.
To make it updatable, I make the trigger for the view which calculate
back the DUR_HOUR and DUR_MIN to its underlying field
DURATION_MINUTES. It is also a simple math:
Total_Minutes = Hour*60 + Minutes
Displaying the view's data runs great. However, updating the view is
odd, the values stored to field DURATION_MINUTES in the underlying
table are the DUR_HOUR values (decreasing by 60 factor).
Do I miss something obvious here?
Below is the script to reproduce the symptom.
== 8< The DDL =====
CREATE DATABASE 'JUST_TEST.FDB' user 'SYSDBA' password 'masterkey';
CREATE TABLE DURATION ( ID integer, DURATION_MINUTES integer);
CREATE VIEW VIEW_DUR ( ID,DUR_HOUR,DUR_MIN)
as SELECT ID,
cast( DURATION_MINUTES/60 as INTEGER),
cast( DURATION_MINUTES - ((DURATION_MINUTES/60)*60) as integer)
from DURATION;
SET TERM ^ ;
CREATE TRIGGER UPDATE_VIEW_DUR FOR VIEW_DUR ACTIVE
BEFORE INSERT OR UPDATE OR DELETE POSITION 0
AS
BEGIN
if (INSERTING) then begin
INSERT INTO DURATION (ID,DURATION_MINUTES)
values (NEW.ID,NEW.DUR_HOUR*60+NEW.DUR_MIN);
end
if (UPDATING) then begin
UPDATE DURATION
set ID=NEW.ID,
DURATION_MINUTES=NEW.DUR_HOUR*60+NEW.DUR_MIN
where ID=OLD.ID;
end
if (DELETING) then begin
DELETE from DURATION where ID=OLD.ID;
end
END^
SET TERM ; ^
COMMIT;
== 8< =====
--Populate record
INSERT INTO DURATION (ID,DURATION_MINUTES) VALUES (1,960);
COMMIT;
--Query is okay
SELECT * FROM VIEW_DUR;
SQL> SELECT * FROM VIEW_DUR;
ID DUR_HOUR DUR_MIN
============ ============ ============
1 16 0
--Just try to update with it self and see what's happend
SQL> update VIEW_DUR set ID=ID;
SQL> commit;
SQL> SELECT * FROM VIEW_DUR;
ID DUR_HOUR DUR_MIN
============ ============ ============
1 0 16
Very strange!
Can somebody enlighten me? I am using FB 1.5.3 on Win2000 SP4.
TIA,
--
Bambang P.
let us call it DURATION_MINUTES
To make it more "user friendly" then I make a view which split the
DURATION_MINUTES in 2 integer fields: DUR_HOUR, DUR_MIN by simple math:
Hour = Total_Minutes/60
Minute = Total_Minutes - ((Total_Minutes/60)*60)
Note: integer division results in integer.
To make it updatable, I make the trigger for the view which calculate
back the DUR_HOUR and DUR_MIN to its underlying field
DURATION_MINUTES. It is also a simple math:
Total_Minutes = Hour*60 + Minutes
Displaying the view's data runs great. However, updating the view is
odd, the values stored to field DURATION_MINUTES in the underlying
table are the DUR_HOUR values (decreasing by 60 factor).
Do I miss something obvious here?
Below is the script to reproduce the symptom.
== 8< The DDL =====
CREATE DATABASE 'JUST_TEST.FDB' user 'SYSDBA' password 'masterkey';
CREATE TABLE DURATION ( ID integer, DURATION_MINUTES integer);
CREATE VIEW VIEW_DUR ( ID,DUR_HOUR,DUR_MIN)
as SELECT ID,
cast( DURATION_MINUTES/60 as INTEGER),
cast( DURATION_MINUTES - ((DURATION_MINUTES/60)*60) as integer)
from DURATION;
SET TERM ^ ;
CREATE TRIGGER UPDATE_VIEW_DUR FOR VIEW_DUR ACTIVE
BEFORE INSERT OR UPDATE OR DELETE POSITION 0
AS
BEGIN
if (INSERTING) then begin
INSERT INTO DURATION (ID,DURATION_MINUTES)
values (NEW.ID,NEW.DUR_HOUR*60+NEW.DUR_MIN);
end
if (UPDATING) then begin
UPDATE DURATION
set ID=NEW.ID,
DURATION_MINUTES=NEW.DUR_HOUR*60+NEW.DUR_MIN
where ID=OLD.ID;
end
if (DELETING) then begin
DELETE from DURATION where ID=OLD.ID;
end
END^
SET TERM ; ^
COMMIT;
== 8< =====
--Populate record
INSERT INTO DURATION (ID,DURATION_MINUTES) VALUES (1,960);
COMMIT;
--Query is okay
SELECT * FROM VIEW_DUR;
SQL> SELECT * FROM VIEW_DUR;
ID DUR_HOUR DUR_MIN
============ ============ ============
1 16 0
--Just try to update with it self and see what's happend
SQL> update VIEW_DUR set ID=ID;
SQL> commit;
SQL> SELECT * FROM VIEW_DUR;
ID DUR_HOUR DUR_MIN
============ ============ ============
1 0 16
Very strange!
Can somebody enlighten me? I am using FB 1.5.3 on Win2000 SP4.
TIA,
--
Bambang P.