Hi All,

I'm using triggers to make my views updatable (ie the user can edit the values view because SQLite will instead change the related source table value). Which method is best to facilitate this?:

1. Use the "instead of update on ViewName" syntax. Trigger on the update of the view as a whole (ie any column triggers the one update).

or:

2. Use the "instead of update of ColumnName on ViewName" syntax in a trigger for each column. Trigger on the update of each column/field individually.

It seems to me that triggering on the view as a whole would unnecessarily update multiple values/columns when only one is changed. On the other hand, adding a trigger for each column seems overkill. Which is the best way?

Below is the complete SQL of a simplified example, where I have an Orders table and a Products table, (which lists the Products in each order). I have an "Orders Calc" view which shows fields from the Orders table, along with a sum() calculation of the Products in that Order.

The result of the SQL by both methods is the same:

Testing method 1: Create a trigger for the view as a whole:
10001|Apple|22.0|1020.0|Cheque|2007-07-21|R1234|2007-07-21
10001|Apple|22.0|1020.0|Cheque|2007-07-22|R1234|2007-07-21
SQL error near line 85: You cannot change the Total, since it is calculated.

Testing method 2: Create a trigger for the view per column:
10001|Apple|22.0|1020.0|Cheque|2007-07-21|R1234|2007-07-21
10001|Apple|22.0|1020.0|Cheque|2007-07-23|R1234|2007-07-21
SQL error near line 154: You cannot change the Total, since it is calculated.

Any personal approaches or revelations welcome :-)

Thanks,
Tom

/*
        Create the test tables and view.
*/

create table Orders
(
        "Order ID" integer primary key autoincrement,
        Supplier text,          -- name of supplier
        Delivery real,          -- delivery cost in dollars
"Paid Method" text, -- method of payment, such as deposit, credit card, cash
        "Paid Date" date,     -- date that payment was sent
        Receipt text,           -- payment receipt
        Ordered date            -- date that the order was sent
);

create table if not exists Products
(
        "Order ID" integer,   -- Orders foreign key
        Code text,              -- Product Code
        Description text,       -- Product Description
        Buy real,               -- Buy price I pay when ordering this item
        Quantity integer        -- Quantity of this product in this order
);
        
create view "Orders Calc"
as
        select
                Orders."Order ID" as "Order ID",
                Supplier,
                Delivery,
                sum( Quantity * Buy ) + Delivery
                        as Total,
                "Paid Method",
                "Paid Date",
                Receipt,
                Ordered
        from Orders
        left join Products
                on Orders."Order ID" = Products."Order ID"
        group by Orders."Order ID";

/*
        Insert Test data
*/

begin;
insert into Orders values ( 10001, 'Apple', 22.0, 'Cheque', '2007-07-21', 'R1234', '2007-07-21');
insert into Products values ( 10001, 'IPH8GB', 'iPhone 8GB', 499.0, 2 );
commit;

/*
        Method 1: Create a trigger for the view as a whole
*/

create trigger "Update Orders Calc"
instead of update on "Orders Calc"
for each row
begin
        update Orders
                set
                        Supplier = new.Supplier,
                        Delivery = new.Delivery,
                        "Paid Method" = new."Paid Method",
                        "Paid Date" = new."Paid Date",
                        Receipt = new.Receipt,
                        Ordered = new.Ordered
                where "Order ID" = new."Order ID";
        select
                case
                        when old.Total != new.Total
then raise( abort, 'You cannot change the Total, since it is calculated.')
                end;
end;

/*
        Test method 1
*/

begin;
select 'Testing method 1: Create a trigger for the view as a whole:';
select * from "Orders Calc";
update "Orders Calc"
        set "Paid Date" = '2007-07-22' where "Order ID" = 10001;
select * from "Orders Calc";
update "Orders Calc"
        set Total = 300.0 where "Order ID" = 10001;
rollback;

/*
        Method 2: Create a trigger for the view per column
*/

drop trigger if exists "Update Orders Calc";

create trigger "Update Orders Calc Supplier"
instead of update of Supplier on "Orders Calc"
for each row
begin
update Orders set Supplier = new.Supplier where "Order ID" = new."Order ID";
end;

create trigger "Update Orders Calc Delivery"
instead of update of Delivery on "Orders Calc"
for each row
begin
update Orders set Delivery = new.Delivery where "Order ID" = new."Order ID";
end;

create trigger "Update Orders Calc Paid Method"
instead of update of "Paid Method" on "Orders Calc"
for each row
begin
update Orders set "Paid Method" = new."Paid Method" where "Order ID" = new."Order ID";
end;

create trigger "Update Orders Calc Paid Date"
instead of update of "Paid Date" on "Orders Calc"
for each row
begin
update Orders set "Paid Date" = new."Paid Date" where "Order ID" = new."Order ID";
end;

create trigger "Update Orders Calc Receipt"
instead of update of Receipt on "Orders Calc"
for each row
begin
update Orders set Receipt = new.Receipt where "Order ID" = new."Order ID";
end;

create trigger "Update Orders Calc Ordered"
instead of update of Ordered on "Orders Calc"
for each row
begin
update Orders set Ordered = new.Ordered where "Order ID" = new."Order ID";
end;

create trigger "Update Orders Calc Total"
instead of update of Total on "Orders Calc"
for each row
begin
select raise( abort, 'You cannot change the Total, since it is calculated.');
end;

/*
        Test method 2
*/

begin;
select 'Testing method 2: Create a trigger for the view per column:';
select * from "Orders Calc";
update "Orders Calc"
        set "Paid Date" = '2007-07-23' where "Order ID" = 10001;
select * from "Orders Calc";
update "Orders Calc"
        set Total = 400.0 where "Order ID" = 10001;
rollback;


-----------------------------------------------------------------------------
To unsubscribe, send email to [EMAIL PROTECTED]
-----------------------------------------------------------------------------

Reply via email to