I want to see if can I use mysql to manage a little stock.
table A contain all the movements:
art_code, qty_load, qty_unload, date
table B with the existence:
art_code, total_load, total_unload, available, date
I've created a trigger: (after update on)
INSERT INTO STOCK VALUES(NEW.ART_CODE, TOTAL_LOAD, TOTAL_UNLOAD, TOTAL_LOAD-TOTAL_UNLOAD, NOW());
but after the first correct run it says a row already exists, how could I replace the old row with the new row?
You can use INSERT ... ON DUPLICATE KEY UPDATE command. It will help you to insert and to update existed records using one statement.
INSERT ... ON DUPLICATE KEY UPDATE Syntax
Related
I have a MySQL database and I need to auto increment a column by 1 every time I do an insert or update. If I had to increment the column only during insert I could have used the built-in autoincrement option (usually used for primary keys). How can I do it for insert and updates?
EDIT
Sorry, I posted the wrong question, what I actually need is to increase a counter by 1 every time I do an insert or update, the current value of the counter has to be stored in the row being created or updated. The counter starts from 1 and never comes back, it just keep increasing "forever" (BIGINT). Think of this counter as a lastupdate timestamp but instead of using real unix timestamps I use an ever increasing integer (monotonic increasing value).
P.S. I'm implementing a syncronization mechanism between many local SQLite databases and one master MySQL database so the behavior has to be implemented on both dbms.
The current state of the counter can be stored on a separate table of course
Simply use triggers.
Something like this:
CREATE TRIGGER trgIU_triggertestTable_UpdateColumnCountWhenColumnB
ON dbo.triggertestTable
AFTER INSERT,UPDATE
AS
BEGIN ...
OR you can do something like this:
INSERT INTO TableA (firstName, lastName, logins) VALUES ('SomeName', 'SomeLastName', 1)
ON DUPLICATE KEY UPDATE count = count + 1;
I see two ways to do what you want.
The first is for inserts, when you should use the autoincrement key. But, when we talk about autoincrement updates, it's a little bit more complicated. For me, the best solution is to do a trigger.
You could use a trigger like this:
CREATE TRIGGER update_trigger
AFTER UPDATE
ON `your_table`
FOR EACH ROW
BEGIN
UPDATE `your_table`
SET `the_field_you_want_autoincrement` = `the_field_you_want_autoincrement` + 1
WHERE `pk` = NEW.pk
END
There's no declarative auto-increment-on-update feature. And the auto-increment must be part of your primary key, so this is probably not your counter.
You can do this with triggers.
CREATE TRIGGER MyTrigger BEFORE INSERT ON MyTable
FOR EACH ROW
SET NEW.counter = 1;
CREATE TRIGGER MyTrigger BEFORE UPDATE ON MyTable
FOR EACH ROW
SET NEW.counter = OLD.counter+1;
These must be BEFORE triggers, because you can't set column values in an AFTER trigger.
Re your comments:
I don't get the "for each row on the second statement"
This is a required clause for all MySQL triggers, because the trigger runs for each row inserted. You can insert multiple rows in a single INSERT statement:
INSERT INTO MyTable VALUES (...), (...), (...), ...
INSERT INTO MyTable SELECT ... FROM ...
The insert trigger will initialize each row inserted.
Re your updated question:
The solution with triggers I show above will actually work for the scenario you describe, where you want a counter column to start at 1 at INSERT time, and increase by 1 every time you update.
The solution with INSERT...ON DUPLICATE KEY UPDATE does not work, because it won't increment the counter if a user simply does an UPDATE statement. Also the user is required to include the initial counter value 1 in their INSERT statement.
The insert trigger sets the initial value to 1 even if a user tries to give a different value in their INSERT statement. And the update trigger will increment the counter even if the user uses INSERT...ON DUPLICATE KEY UPDATE or UPDATE.
But don't use a REPLACE statement, because this would do a DELETE followed by a new INSERT, and thus it would run the insert trigger, and reset the counter to 1.
This is my problem:
Create a trigger which will add the id and age columns of rows deleted
from the table "metadata" to the "metadata2" table.
The query that will be run to check if the trigger works is:
DELETE FROM metadata WHERE ID=40124197; SELECT * FROM metadata2.
So, what did I do? I did this:
CREATE TRIGGER somerandomtrigger
AFTER INSERT ON metadata2
FOR EACH ROW
BEGIN
INSERT INTO metadata2 (id, age)
END
Yet it keeps saying: Query failed: near "END": syntax error, but I don't get why.
It seems you used the wrong event trigger on the worng table.
When you delete a record from metadata table, you want to insert some data from this record into metadata2.
On delete trigger, there is a a records managed by MySQL named OLD containing the record that has been deleted.
CREATE TRIGGER somerandomtrigger
AFTER DELETE ON metadata
FOR EACH ROW
BEGIN
INSERT INTO metadata2(id, age) VALUES (OLD.id, OLD.age);
END;
Syntax and examples of MySQL trigger
I tried it with the help of this query "insert into class(faculty_id) select faculty_id from faculty;" but it is inserting already existing values only. Here one column of the table is under auto-increment so I wanted to take this incremented values to another table's column in mysql workbench 6.2. I even tried setting a foreign key between the two columns but it dint work. Please can anyone help out with this issue??
This is what you want i think. an after insert trigger will fire every time something is inserted into faculty, and after the data has been inserted. You can access the values that have just been inserted with the NEW. prefix.
DELIMITER //
create trigger classInsert after insert on faculty
for each row
begin
insert into class(faculty_id) values (NEW.faculty_id);
end//
DELIMITER ;
And it will automatically add an entry into the class table every time you add a new value to faculty.
Fiddle example
I'm using Mysql in phpMyAdmin,where i have to delete a entry from tableA if i insert a row with same primary key.I thought to do it in trigger of tableA BEFORE INSERT
For Ex,
if the tableA contains
1 Hai Hello
here 1 is the primary key
And now if i insert a row 1 Bye Hello then the trigger BEFORE INSERT will delete the old entry and then the new row (2nd) will be inserted. But Mysql has restriction of not being able to update a table inside a trigger defined for that same table.
It gives the error
#1442 - Can't update table 'tableA' in stored
function/trigger because it is already used by statement which invoked
this stored function/trigger.
So i changed my way, i called a procedure from trigger BEFORE INSERT of tableA and in that procedure i do the task what i thought to do in trigger. But unfortunately i'm getting the same error.
In trigger BEFORE INSERT i simply called the procedure as
CALL proce1(new.Reg_No);
In procedure i have done this
DECLARE toup integer;
select count(*) into toup from tableA where Reg_No=reg;/*Here Reg_No is primary key */
if toup > 0 then
delete from tableA where Reg_No=reg;
end if;
Need some other Idea to achieve this. Help Me.....
I don't like to use triggers so much because they are hard to manage somethimes. Also they will cause you a downgrade in performance. I am not against trigger as they can be handy in some cases.
In your case have you though of using REPLACE(....) or INSERT INTO .... ON DUPLICATE KEY UPDATE or even INSERT INTO IGNORE .....
REPLACE(....) will delete a record if a record is found and insert a new one with the same ID.
INSERT INTO .... ON DUPLICATE KEY UPDATE will allow you to override existing field if a duplicate is found.
INSERT INTO IGNORE ..... will allow you to ignore the new inserted row if one already exists
Since you mentioned in the comments that you are importing records from a file, then try to use LOAD DATA INFILE logic which will allow you to REPLACE field on duplicate
LOAD DATA LOCAL INFILE 'x3export.txt'
REPLACE INTO TABLE x3export
Using MySQL and PHP, I have two tables ResponseTable and EntryTable
Response table has
RespID(pk,uq,ai, int), Response(string)
Entry table has
EntryID(pk,uq,ai,int), RespID(int), UserID(int)
I would like to insert a response into the ResponseTable where the Response doesn't exist, and then insert an entry into the EntryTable based on the RespID from the ResponseTable corresponding to the response.
How can this be done with the fewest statements?
EDIT:
Response is unique
The fewest statements from the front-end would be to use a stored procedure. Any way you do it, though, you will still need to have two INSERT statements. You just can't insert two different things with one query.
mysql supports TRIGGERS . you can add one to your ResponseTable that will activate "AFTER" "INSERT" and you can get it to use the values that are being inserted using the NEW key word.
the body of the trigger can be an insert into entry
something like:
CREATE TRIGGER `response_after_insert` AFTER INSERT ON `response`
FOR EACH ROW
BEGIN INSERT INTO entry SET RespID=NEW.RespID ON DUPLICATE KEY UPDATE operation=1;END;
So once you have your trigger set up, any time you do an insert on respnse, the trigger will get activated