Updating a singular row in a trigger SQLite - sqlite

Table rental has values (ID, odo_out, date),
table vehicle has values (ID, odo, car),
both with more columns but not relevant to this.
I have attempted to create a trigger:
CREATE TRIGGER odo_update AFTER INSERT ON rental
BEGIN
UPDATE rental SET odo_out = (SELECT Vehicle.odo FROM Vehicle WHERE rental.ID = Vehicle.ID)
WHERE EXISTS (SELECT * FROM Vehicle WHERE Vehicle.ID = rental.ID);
END;
which should detect a NULL for rental.odo_out and replace it with the value in Vehicle.odo for corresponding ID. This does work, but it updates every row in table, whereas I want it to ONLY update the row with NULL, ie the new row being inserted. An ID can be repeated multiple times in the rental table. How can I do this?

You must set the condition so that only the new row is updated.
This is where you need the keyword NEW to refer to the columns of the new row:
CREATE TRIGGER odo_update AFTER INSERT ON rental
WHEN NEW.odo_out IS NULL
BEGIN
UPDATE rental
SET odo_out = (SELECT odo FROM Vehicle WHERE ID = NEW.ID)
WHERE ID = NEW.ID;
END;

Related

MariaDB - delete all values that are `not the max` of one column with a group by on another column

I have a table that is a list of updates over time timeOfOfferChange. I can grab the most recent value with the query below but is there a way to delete all the records that are not the max?
select asin, uniqueid, max(timeOfOfferChange) from tbl_sqs group by asin
You could use exists logic:
DELETE
FROM tbl_sqs t1
WHERE uniqueid NOT IN (SELECT uniqueid
FROM (
SELECT t2.uniqueid
FROM tbl_sqs t2
WHERE t2.asin = t1.asin AND
t2.timeOfOfferChange > t1.timeOfOfferChange
) t);

INSTEAD OF AND COMPOUND INTEGER

C. Create an INSTEAD OF row trigger on EMP_VU that increases the current count for a department by 1 if a new employee is added and subtracts 1 from the count for a department if an employee is deleted
create or replace trigger count_trigger
instead of insert or delete on emp_vu
begin
if deleting then
update dept_count
set count_emps = count_emps - 1
where dept_id = :OLD.department_id ;
elsif inserting then
update dept_count
set count_emps = count_emps + 1
where dept_id = :NEW.department_id ;
end if ;
end ;
/
D. Look at the counts for all departments in DEPT_COUNT. Test to see if your trigger fires correctly by inserting a row into EMP_VU. Look at the count for the department of the new employee. Delete a row from EMP_VU. Look at the count for the department where the employee was just deleted.
SELECT * FROM dept_count;
INSERT INTO emp_vu VALUES (606, 'Sillins', 90);
DELETE FROM emp_vu WHERE employee_id = 606;
Excuse me is there anyone help to repair this query?

Sqlite trigger to calculate an ID based on an entry type

I am trying to setup a trigger that will auto calculate an ID field based on the sum of a specific type of entry. I have it working where the ID number in the ID indexes based on the number of all entries
> BEGIN
> UPDATE master_workorders
> SET wo_no = master_workorders.wo_sub || substr('0000'||master_workorders.pkuid, -4,4)||'-'|| substr(master_workorders.rdate,3,2)
> WHERE rowid = NEW.rowid;
> END
This returns ID's like WO0001-17 BB0002-17 and M0003-17 each ID number (middle 4 digits) is an entry. I want my ID numbers to represent the number of each type (WO, BB, M these values are stored in the wo_sub column) as WO0001-17 BB0001-17 M0001-17 and if a new BB work order is added it would be BB0002-17 and so on for each type.
To replace the autoincremented ID with the current count, replace master_workorders.pkuid with a subquery:
... || (SELECT COUNT(*) FROM master_workorders WHERE wo_sub = NEW.wo_sub) || ...

Inserting new id from sequence into table column id and insert that same id to another table without dual table

I have a table:
create table osoba (osoba_id number,
ime_osobe varchar2(200),
prezime_osobe varchar2(200),
kartica_id number)
create table kartica (kartica_id number,
dozvoljen_ulaz_id number)
I need to make procedure that
Inserts data into table osoba.
Checks if there is data in table kartica column kartica_id.
If there is, add that id to column kartica_id in table osoba.
If there isn't, then add kartica_id in kartica table by sequence I have created and then add that newly created kartica.kartica_id to kartica_id in table osoba.
Kartica_id in kartica and kartica_id in osoba must be unique and only one kartica_id for one record in osoba for that exact record (person added).
If there is already a kartica_id added to osoba.kartica_id of the same value then throw error message 'Kartica_id already exists. No same values allowed.' and insert next new kartica_id value to kartica table and pass that value to kartica_id in table osoba.
I'm new to pl/sql so this is where I got so far:
create or replace procedure insertOsoba
( o_osoba_id in osoba.osoba_id%type default generate_id.nextval,
o_ime_osobe in osoba.ime_osobe%type,
o_prezime_osobe in osoba.prezime_osobe%type,
o_kartica_id in kartica.kartica_id%type default null --must be optional
)
is
begin
insert into osoba (osoba_id,ime_osobe,prezime_osobe,kartica_id)
values (o_osoba_id,o_ime_osobe,o_prezime_osobe,o_kartica_id);
end insertosoba;
I'm posting solution where I use kartica_seq as a sequence for kartica_id. Please replace it with your sequence name or create sequence if it not exist.
create sequence kartica_seq start with 1 increment by 1;
create or replace procedure insertOsoba
( o_osoba_id in osoba.osoba_id%type default generate_id.nextval,
o_ime_osobe in osoba.ime_osobe%type,
o_prezime_osobe in osoba.prezime_osobe%type,
o_kartica_id in kartica.kartica_id%type default null --must be optional
)
is
cnt number;
cnt2 number;
begin
select count(*) into cnt from osoba where kartica_id = o_kartica_id;
select count(*) into cnt2 from kartica where kartica_id = o_kartica_id;
if(cnt = 0) then
--there is no person with such kartica and user passed existing kartica_id
if(o_kartica_id is not null and cnt2 > 0) then
insert into osoba (osoba_id,ime_osobe,prezime_osobe,kartica_id)
values (o_osoba_id,o_ime_osobe,o_prezime_osobe,o_kartica_id);
--there is no person with such kartica but we need to create one entry using sequence
else
insert into kartica (kartica_id) values (kartica_seq.nextval);
insert into osoba (osoba_id,ime_osobe,prezime_osobe,kartica_id)
values (o_osoba_id,o_ime_osobe,o_prezime_osobe,kartica_seq.currval);
end if;
end if;
--there is person with such kartica
if(cnt > 0) then
dbms_output.put_line('Kartica_id already exists. No same values allowed.'); --or raise an exception here
end if;
commit;
end insertosoba;

trigger insert different row

The sqlite3 trigger that I want to create might or might not be possible with sql. Five tables are involved:
Members Groups GroupMembers Accounts
mId |name| accId gId | name | accId gId | mId accId | balance
Orders
oId | accId | ammount
When someone deletes a group, I want to make an order for each of the group members with the average of the group balance. So it should do something like this:
CREATE NEW TRIGGER triggername
BEFORE DELETE ON Groups
WHEN ((SELECT balance FROM Accounts WHERE accId=OLD.accId) = 0)
FOR EACH ROW IN
(SELECT accId
FROM GroupMembers JOIN Members ON GroupMembers.mId = Members.mId
WHERE GroupMembers.gId = OLD.gId)
BEGIN
INSERT INTO Orders(accId,ammount) VALUES(accId,
(SELECT balance FROM Accounts WHERE accId = OLD.accId)
/
(SELECT SUM(mId) FROM GroupMembers WHERE gId = OLD.gId)
);
END
The question is: is it possible to create a FOR EACH ROW in any other table than the table at which the trigger applies? Is it possible to put the WHEN statement before the FOR EACH statement?
As documented, there is no such a thing as a FOR EACH ROW IN ... clause.
However, the INSERT statement can use a SELECT statement as the source of the data to be inserted.
Write a SELECT statement that returns one row for each group member:
CREATE TRIGGER triggername
AFTER DELETE ON Groups
FOR EACH ROW
BEGIN
INSERT INTO Orders(accId, amount)
SELECT accId,
(SELECT balance
FROM Accounts
WHERE accId = OLD.accId) /
(SELECT COUNT(*)
FROM GroupMembers
WHERE gId = OLD.gId)
FROM Members
WHERE mId IN (SELECT mId
FROM GroupMembers
WHERE gId = OLD.gId);
END;
(I dropped the balance = 0 filter.)

Resources