how to get last modified column name from mysql - mysql

Is it possible to get a particular updated column name from a record?
if so, please help me. since i am creating a history table to store a updated column and their values from rest of the tables.
DROP TRIGGER IF EXISTS testing.hisupdate;
CREATE TRIGGER testing.hisupdate AFTER
UPDATE ON testing.emp
FOR EACH ROW
INSERT INTO testing.history (`id`,`revision_id`,`trx_code`, `trx_method`, `column_name`, `old_value`, `new_value`, `trx_timestamp`, `user_id`)
SELECT
(SELECT emp_id
FROM testing.emp
ORDER BY last_update DESC LIMIT 1),
(SELECT p.revision_id
FROM testing.history AS p
WHERE p.id=
(SELECT emp_id
FROM testing.emp
ORDER BY last_update DESC LIMIT 1)
ORDER BY trx_timestamp DESC LIMIT 1) + 1, 'updt', 'update','null',
(SELECT p.new_value
FROM testing.history AS p
WHERE p.id=
(SELECT emp_id
FROM testing.emp
ORDER BY last_update DESC LIMIT 1)
ORDER BY trx_timestamp DESC LIMIT 1), concat(p.emp_id,"/",p.emp_name,"/",p.salary,"/") AS new_value,
NOW(),
'101'
FROM testing.emp AS p
WHERE p.emp_id = new.emp_id;
i have created trigger but searching for a sub query for last updated column name..
thanks in advance.

Try this code...
create table sales(orderno INT, sale INT,empsalary int, ts TIMESTAMP);
create table history(updated varchar(20), oldvalue INT,newvalue INT);
INSERT INTO sales (orderno,sale,empsalary) VALUES(1,700,7000);
INSERT INTO sales (orderno,sale,empsalary) VALUES(2,800,8000);
INSERT INTO sales (orderno,sale,empsalary) VALUES(3,900,9000);
DROP TRIGGER test.instrigger;
DELIMITER ///
CREATE TRIGGER test.instrigger AFTER UPDATE ON sales
FOR EACH ROW
BEGIN
IF NEW.sale <> OLD.sale THEN
INSERT INTO history (updated, oldvalue, newvalue) VALUES('sale', OLD.sale,NEW.sale);
END IF;
IF NEW.empsalary <> OLD.empsalary THEN
INSERT INTO history (updated, oldvalue, newvalue) VALUES('empsalary', OLD.empsalary,NEW.empsalary);
END IF;
END;
///
DELIMITER ;

Related

Why is my procedure populating separate rows?

My stored procedure is populating different rows and I need it to populate a single row. I have tried adding in some where clauses but that breaks it. Any help is appreciated!
DELIMITER //
CREATE PROCEDURE Populate()
BEGIN
insert into log(NoEmp) (select count(empid) from emp);
insert into log(NoDept) (select count(deptid) from dept);
insert into log(LocReg1) (select count(regionid) from region where regionid=1);
insert into log(LocReg2) (select count(regionid) from region where regionid=2);
insert into log(LocReg3) (select count(regionid) from region where regionid=3);
insert into log(TotSales) (select sum(salesamt) from sales);
insert into log(AvgSaleMo) (select TotSales/(24) from log);
insert into log(AvgSaleYr) (select TotSales/(2) from log);
insert into log(logdate) (select NOW());
END //
DELIMITER ;
Every time you INSERT it creates a new row (unless you use the ON DUPLICATE KEY UPDATE clause).
If you want to insert a single row, use a single INSERT with multiple columns and values.
INSERT INTO log (NoEmp, NoDept, LocReg1, LocReg2, LocReg3, TotSales, AvgSaleMo, AvgSaleYr, logdate)
VALUES (
(select count(empid) from emp),
(select count(deptid) from dept),
(select count(regionid) from region where regionid=1),
(select count(regionid) from region where regionid=2),
(select count(regionid) from region where regionid=3),
(select sum(salesamt) from sales),
(select sum(salesamt)/(24) from sales),
(select sum(salesamt)/(2) from sales),
NOW()
);

Create a trigger that updates another table when a new item is inserted

I have a table rating(idrating,clientno,spid,rating) and serviceprovider(spid,name,totalrating).
I want to create a trigger such that it avg all the rating of the spid and put it in the totalrating column. What's the best way to do so? or is it impossible for a trigger?
This should work:
CREATE TRIGGER `INSERT_TOTAL` AFTER INSERT ON `rating`
FOR EACH ROW INSERT INTO serviceprovider( spid, name, totalrating )
VALUES (
NEW.spid, 'name', (
SELECT AVG( spid )
FROM rating
)
)
With update:
CREATE TRIGGER `INSERT_TOTAL` AFTER INSERT ON `rating`
FOR EACH ROW
UPDATE serviceprovider SET totalrating = ( SELECT AVG( spid ) FROM rating )
WHERE name = 'name'

Appending additional SQL tigger to existing trigger

I have the following SQL update trigger that works properly:
BEGIN
DECLARE myID INT;
SELECT user_id INTO myID FROM writer WHERE writer_id = NEW.writer_id;
IF (NEW.status_id = 2) THEN
INSERT INTO activity (
user_id,
work_id,
activity,
date_created
) VALUES (
myID,
NEW.work_id,
'confirmed',
now()
);
ELSE
INSERT INTO activity (
user_id,
work_id,
activity,
date_created
) VALUES (
myID,
NEW.work_id,
'modified',
now()
);
END IF;
END
I need to add an additional trigger as the following:
CREATE TRIGGER updateWorkStatus AFTER UPDATE ON writer_split
FOR EACH ROW
BEGIN
UPDATE work a
JOIN writer_split b
ON a.work_id = b.work_id AND a.current_version = b.version
SET a.status_id = 2
WHERE a.work_id NOT IN (
SELECT ab.work_id
FROM (SELECT s.work_id
FROM work w INNER JOIN writer_split s
ON w.work_id = s.work_id AND s.status_id != 2) ab
);
END;
when I run this create script, I am getting a syntax error. Any ideas?
For me i will use UPDATE work as a

Create trigger to increase value when found duplicate

I need to make trigger to increase the 2nd digit when the new value found to be a duplicate.
For Instance, I have a unique filed with 10 digits value. I want when someone insert same number it increase the second left digit like 0100012345. How I can do that? Thank you.
FirstName LastName Code
Houssam Salim 0100012345 to be 0200012345
Try this
I have found a solution with instead off trigger
'/*
CREATE TABLE [Employee1]
(
[id] VARCHAR(20) PRIMARY KEY,
[name] VARCHAR(50)
)
CREATE TRIGGER AutoIncrement_Trigger
ON [Employee1]
instead OF INSERT
AS
BEGIN
DECLARE #ch CHAR
DECLARE #num INT
IF EXISTS (SELECT 1
FROM Employee1 e
JOIN inserted i
ON i.id = e.id)
BEGIN
SET #num=(SELECT max(CONVERT(INT, substring(e.id, 1, 2))) + 1
FROM employee1 e
JOIN inserted i
ON substring(e.id, 3, len(e.id)) = substring(i.id, 3, len(i.id)))
INSERT INTO [Employee1]
(id,
name)
SELECT '0' + CONVERT(VARCHAR(10), #num)
+ substring(i.id, 3, len(i.id)),
e.name
FROM Employee1 e
JOIN inserted i
ON i.id = e.id
END
ELSE
BEGIN
INSERT INTO [Employee1]
(id,
name)
SELECT inserted.id,
inserted.name
FROM inserted
END
END
*/
INSERT INTO [Employee1]
VALUES ('0100012345',
'John')
SELECT *
FROM [Employee1]
INSERT INTO [Employee1]
VALUES ('0100012345',
'John')
SELECT *
FROM [Employee1]
'

Insert query based on number of rows

I want a query to insert a row into a table I know it is simple but the scenario is the table should not have more than 5 rows. If table has more than five rows I need to remove the old row(Or replace with new row ) (Based on the insert time stamp) then i need to insert a new row.If number of rows less than count 5 then i can directly insert a row.
Please share me the query.
How about something like this.
declare #count int
SELECT #count=COUNT(*)
from EP_ANSWERS
IF (#count<5)
// DO your insert here
ELSE
DELETE FROM TABLE
WHERE inserttimestamp = (SELECT x.inserttimestamp
FROM (SELECT MAX(t.inserttimestamp) AS inserttimestamp
FROM TABLE t) x)
// DO your insert here
If it is impossible for the table to have more than 5 rows:
DELETE FROM yourtable
WHERE 5 <= (SELECT COUNT(*) FROM yourtable)
AND yourtimestamp = (SELECT MIN(yourtimestamp) FROM yourtable)
;
INSERT INTO yourtable ...
;
If it is possible for the table to have more than 5 rows:
DELETE FROM yourtable
WHERE 5 <= (SELECT COUNT(*) FROM yourtable)
AND yourtimestamp NOT IN (SELECT yourtimestamp
FROM yourtable
ORDER BY yourtimestamp DESC
LIMIT 4)
;
INSERT INTO yourtable ...
;
It sounds like you want to put a trigger on the table to maintain this rule, in MySQL the something like this should work
CREATE TRIGGER trg__my_table__limit_rows
BEFORE INSERT
ON my_table
FOR EACH ROW
BEGIN
IF ((SELECT COUNT(1) FROM my_table) = 5)
BEGIN
DELETE FROM my_table
WHERE id = (SELECT MIN(id) FROM my_table) -- change this to fit your logic for which record should be removed
END
END
Some of the code here is in pseudo (you didn't wrote your schema), but i wrote where you need to complete your own code.
DECLARE #NumberOfRowsToInsert INT = -- select from the data you want to insert
DECLARE #MaxNumberOfRows INT = 5
DECLARE #NumberOfExistingRows INT
DECLARE #Query VARCHAR(MAX) = 'SELECT TOP #rows id FROM SomeTable ORDER BY createdDate ASC'
SELECT #NumberOfExistingRows = COUNT(*)
FROM SomeTable
SET #Query = REPLACE(#Query,'#rows',
CAST(#NumberOfRowsToInsert - (#MaxNumberOfRows - #NumberOfExistingRows))) AS VARCHAR(1))
CREATE TABLE #IdsToDelete(id INT PRIMARY KEY)
INSERT INTO #IdsToDelete
EXEC(#Query)
DELETE FROM SomeTable
WHERE id IN (SELECT * FROM #IdsToDelete)
-- insert here..