On 26/02/2020 12:18, Richard Hipp wrote:
On 2/26/20, Jean-Luc Hainaut <jean-luc.hain...@unamur.be> wrote:
Hi all,
It seems that SQLite (version 31.1) accepts a trigger declaration in
which the name is missing. When fired, this trigger doesn't crashes but
exhibits a strange behaviour. In particular, while expression
"new.<colName>" in an "insert" trigger returns the correct value, the
equivalent expression "select <colName> from T where Id = new.Id" always
returns null (column "Id" is the PK of table "T"). Similarly, "update T
set <columnName> = <expression> where Id = new.Id" (silently) fails.
What is the text of your trigger?
This trigger belongs to a small experimental application I'm writting to
study the extent to what application code (initially in Java, Python,
etc.) can be integrated into SQL, notably through triggers. In short,
can one convert a standard 3-tier business application into just a GUI +
an active database, without the standard application program between them?
The following trigger controls the registration of a customer order
[insert into CUSTORDER(OrdID, CustID,ItemID,Qty,...) values (...)] when
the available quantity (Qavail) of the requested item is sufficient.
If the name 'CORD_INS1' is missing, this trigger (among others):
- updates the ITEM table. [successfully]
- completes the customer order (Price and State in CUSTORDER). [fails]
- creates an invoice (in CUSTINVOICE) and prints it in a text file.
[successfully]
After reading all your explanations and comments, my interpretation is
as follows:
1. The SQLite syntax tells me that the "before/after/instead of" keyword
can be missing, in which case (I guess) "before" is assumed.
2. So, my "name-less" trigger is valid and must be read:
create trigger "after" before insert on CUSTORDER ...
3. In a "before" trigger, the current row cannot be updated, since it
doesn't exist yet (though several RDBMS have a specific syntax for that).
4. This explains why SQLite legitimely ignores the second update.
Am I right?
If I am, this behaviour is "not a bug but a feature". It could be useful
to precise these facts in the documentation.
Thanks to all
Jean-Luc Hainaut
create table CUSTOMER (CustID,Name,Address,City,Account,...);
create table ITEM
(ItemID,Description,Price,QonHand,Qord,Qavail,Qmargin,...);
create table CUSTORDER (OrdID,DateOrd,CustID,ItemID,Price,Qty,State,...);
create table CUSTINVOICE
(InvID,DateInv,OrdID,CustID,ItemID,Price,Qty,Amount,State,...);
create table SUPPLIER (SuppID,Name,City,...);
create table OFFER (SuppID,ItemID,Price,Delay,...);
create table SUPPORDER (OrdID,DateOrd,ItemID,SuppID,Price,Qty,State,...);
create trigger CORD_INS1
after insert on CUSTORDER
for each row
when new.Qty <= (select Qavail from ITEM where ItemID = new.ItemID)
and not exists (select * from CUSTINVOICE where OrdID = new.OrdID)
begin
--
-- Subtract Qty from Qavail:
update ITEM
set Qavail = Qavail - new.Qty
where ItemID = new.ItemID;
--
--...
-- Set CUSTORDER.State to 'invoiced' or 'pending'
update CUSTORDER
set Price = (select Price from ITEM where ItemID = new.ItemID),
State = case when new.Qty <= (select QonHand from ITEM where
ItemID = new.ItemID)
then 'invoiced'
else 'pending'
end
where OrdID = new.OrdID;
--
-- Create an invoice and print it:
insert into CUSTINVOICE(...);
--
end;
_______________________________________________
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users