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?
Related
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;
I want to increment Total by one if we insert the same Name and Age. Otherwise it should be inserted as a new row with count 1.
id Name Age Total
1 Priyanka 23 1
First check if record is there
SELECT * FROM yourTableName WHERE Name = 'your name' AND Age = your
age;
check if you found record from above query then
UPDATE yourTableName SET Total = youraboverecord.total+1 WHERE ID = youraboverecord.id;
Else Simply insert your record.
i have student and trainer tables :
student table:
student_id (primary key)
name
email
trainer table:
trainer_id
student_id
amount
output has to:
sid name email amount
22 ram r#g 200
34 sam r#f
i want to get (student_id,name,email) from student table and (amount) from trainer table(imp : trainer_id and student_id should match(like sid = 46,tid =78,amount=500) then only the amount has to display value. otherwise amount will display empty but (student_id,name,email) should display)
in trainer table, student_id and trainer_id has to match...based on that amount will come..i mean if we send the select query as "select amount from trainer where student_id= 20 and trainer_id=36...". that column should match for sid and tid
If you do it this way, It wil not show data if amount is empty :
select st.student_id,
st.name,
st.email,
tt.amount
from student_table st, trainer_table tt
where st.student_id = tt.student_id
NVL function lets you substitute a value when a null value is encountered,
so if you do it this way, It wil show data and show 0 instead of null:
select st.student_id,
st.name,
st.email,
(nvl(select tt.amount
from trainer_table tt
where st.student_id = tt.student_id,0))) amount
from student_table st
This can be accomplished with PLSQL. Sorry it is so extensive but I hope it allows you to see the power of PLSQL if you need to manipulate data based on conditionals.
DECLARE
TYPE result_record IS RECORD
( sid NUMBER
, name VARCHAR2(60)
, email VARCHAR2(60)
, amount NUMBER);
CURSOR c IS select st.student_id sid,
st.name name,
st.email email,
tt.amount amount
from student_table st, trainer_table tt
where st.student_id = tt.student_id;
TYPE results_table IS TABLE OF results_record INDEX BY BINARY_INTEGER;
c_rec c%ROWTYPE;
temp_rec RESULTS_RECORD;
results RESULTS_TABLE;
lv_index NUMBER := 0;
BEGIN
OPEN c;
WHILE lv_index <= c%ROWCOUNT LOOP
FETCH c INTO c_rec;
temp_rec.sid := c_rec.sid;
temp_rec.name := c_rec.name;
temp_rec.email := c_rec.email;
temp_rec.amount := c_rec.amount;
results(lv_index) := temp_rec;
lv_index := lv_index + 1;
END LOOP;
CLOSE c;
-- Now we can access and modify our table from inside PLSQL
SELECT * FROM results;
-- Use PLSQL logic to make the table output pretty with '$' and conditionals
FOR i IN results LOOP
dbms_output.put_line(i.sid||' $'||i.amount); -- example for how to access
-- your code here
END LOOP;
END;
/
As always, I hope this gives you some ideas.
-V
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.)
I'm trying to verify if data exists in two different tables in a single transaction. The reason for the single transaction is the database gets hit about 1-3 million times a day so adding anymore than 1 extra transaction would increase that number up to 9 million, and my poor little server needs a break :)
So I need to check if an ID exists in table X and table Y and return the results to my VB.net script so I can handle the outcome Ideally something like this would work
if exists (select id from X where id = #id)
print 'True,' else print 'False,'
if exists (select id from Y where id = #id)
print 'True' else print 'False'
Which gives me "True, True" if exists in both or "True, False" etc etc... But that only displays in SQL print and not actually returning it as an object/string or array values that I can use.
I'm open to any sort of solution of this nature that can give me two results from a single transaction and how to handle that response in vb. Thanks
SELECT
Case When EXISTS(SELECT 1 FROM X WHERE id = #id) Then 1 Else 0 End AS IsInX,
Case When EXISTS(SELECT 1 FROM Y WHERE id = #id) Then 1 Else 0 End AS IsInY
select (select COUNT(*) from X where id = #id) AS x_exists,
(select COUNT(*) from Y where id = #id) AS y_exists
This returns one data row with two fields, each containing either 0 or 1 (or more, if id is not unique).
CREATE PROCEDURE CheckIDOnTables(#ID int)
AS
BEGIN
DECLARE #X AS NVARCHAR(10)
DECLARE #Y AS NVARCHAR(10)
Set #X = 'False'
Set #Y = 'False'
if exists (select id from TableX where id = #ID)
Set #X = 'True'
if exists (select id from TableY where id = #ID)
Set #Y = 'True'
SELECT #X AS XExists, #Y AS YEsists
END
It will give you your desired results.