Hello Im trying to find a way the UPDATE or INSERT data with one query.
I have a table with like this:
+------+-------------+
| User | action_type |
+------+-------------+
| Jon | 1 |
| Kate | 2 |
| Jon | 4 |
+------+-------------+
I want to insert new value for Jon only if there is no values of Jon.
If I have values of Jon I want to update all the rows with Jon.
Ive read about INSERT ... ON DUPLICATE KEY UPDATE but I dont have unique values.
Thanks for helping.
you can count the entries for jon. If exists update else insert.
if you want to implement only using sql you can use an stored procedure
something like this:
CREATE PROCEDURE insertorupdate (IN name VARCHAR(20))
BEGIN
DECLARE numJon INT;
SELECT COUNT(*) INTO numJon FROM table WHERE User=name;
IF numJon > 0 THEN
// UPDATE ;
ELSE
// INSERT
END IF;
END
Then you can call you Store Procedure:
CALL insertorupdate('John');
If you can do it from your app you can call the same thing but separatelly. Do a select count, test if count if grater than 0 and then do the insert or the update on DB
Don't count like in user468891's answer. It might become a performance issue. Instead just check if an entry exists. As soon as an entry is found, the query returns true, count continues to find all records.
DELIMITER $$
CREATE PROCEDURE insertorupdate (IN name VARCHAR(20))
BEGIN
IF (EXISTS(SELECT 1 FROM table WHERE User = name)) THEN
// UPDATE...
ELSE
// INSERT...
END IF;
END $$
DELIMITER ;
Related
I have a users_settings table on my db in which I store some data about the user. For some of that data I need to keep track of last modification, for example:
+--------------+-------------+
| Field | Type |
+--------------+-------------+
| feel | varchar(10) |
| feel_last | timestamp |
| other | varchar(10) |
| other_last | timestamp |
+--------------+-------------+
When I update the row with a new feel value I want to automatically write the current timestamp, is it possible to achieve this directly from mysql or I need to set the timestamp directly in the update query from my backend?
Update 1
As suggested I need to use a trigger, I written this trigger but there is some syntax error, can you help me to identify the error?
CREATE TRIGGER users_feel_last BEFORE UPDATE ON users
FOR EACH ROW BEGIN
IF NEW.feel <> OLD.feel THEN
SET NEW.feel_last := now();
END IF;
END;
UPDATE 2
For who use AWS RDS: the parameter "log_bin_trust_function_creators" isn't enabled by default, to create triggers it's necessary, here a small guide to set it: https://aws.amazon.com/it/premiumsupport/knowledge-center/rds-mysql-functions/
Now, thanks to James answer I created the trigger, it works well
DELIMITER $$
CREATE TRIGGER before_feel_last_update
BEFORE UPDATE ON users
FOR EACH ROW
BEGIN
if(old.feel<>new.feel)
then
set new.feel_last=current_timestamp;
elseif( old.feel = NULL )
then
set new.feel_last=current_timestamp;
end if;
END$$
DELIMITER ;
A trigger is not necessary in MySQL. This functionality is happily built in. You can define the table as:
create table users (
. . .,
update_datetime datetime default current_timestamp on update current_timestamp
);
You can read about this default in the documentation.
You can use the below trigger on BEFORE UPDATE
BEGIN
if(old.feel<>new.feel)
then
set new.feel_last=current_timestamp;
end if;
END
I need a trigger in phpmyadmin for 2 tables.
I have two tables called users and group_has_users. Table group_has_users has 2 values called group_id and user_id.
I'm trying to make a trigger that automatically inserts new data to group_has_users table with user_id when new user is created in users table( with group_id set to 1)
How to do this with phpmyadmin trigger?
insert into group_has_users (user_id) values (new.user_id);
I have no clue to make it group_id to set 1.
I think this is what you want:
delimiter $$
create trigger after_insert_users
after insert on users
for each row begin
if new.group_id = 1 then
insert into group_new_users (user_id) values (new.user_id);
end if;
end $$
delimiter ;
Note that you will have to run this in your cli or in mysql workbench
Everytime a new record is created in table users, you are looking to automatically create a new record in group_has_users, with a default group_id of 1.
Consider the following trigger:
DELIMITER //
CREATE TRIGGER users_after_insert
AFTER INSERT ON users FOR EACH ROW
BEGIN
INSERT INTO group_has_users(group_id, user_id) VALUES(1, NEW.user_id);
END;
//
Demo on DB Fiddle:
DELIMITER //
CREATE TABLE users (user_id int)//
CREATE TABLE group_has_users (group_id int, user_id int)//
CREATE TRIGGER users_after_insert
AFTER INSERT ON users FOR EACH ROW
BEGIN
INSERT INTO group_has_users(group_id, user_id) VALUES(1, NEW.user_id);
END;
//
INSERT INTO users(user_id) values(1);
SELECT * FROM group_has_users;
| group_id | user_id |
| -------- | ------- |
| 1 | 1 |
I have a table, which has an ID, a column "A" and other columns. If A is set to "this", there can't be another ID with it's column A set to "this". Else, there can be many entries of that ID with multiple values set for column "A".
Ex.:
ID | A | other columns
this is allowed:
1 | that | ...
1 | something | ...
1 | foo | ...
but this is not:
1 | this | ...
1 | that | ...
(the 3 dots mean it doesn't matter what data we have there)
I'm doing this on MySQL Workbench, so it would be much appreciated if your answer showed me how to do it there.
You need to create a trigger that will fire before every INSERT or UPDATE statement (for each row) and check whether or not your constraint is valid and the row can or cannot be added. AFAIK in MySQL you actually need to have two triggers (one for each action), but there is nothing stopping you from wrapping up your validation within a procedure and call it from both triggers.
I'll give you the starters for further tweaking.
1.Create insert trigger
DELIMITER //
DROP TRIGGER IF EXISTS insert_trg //
CREATE TRIGGER insert_trg
BEFORE UPDATE ON yourtable
FOR EACH ROW
BEGIN
CALL yourprocedure(<arguments here>);
END //
DELIMITER ;
2.Create update trigger analogously to the insert trigger
3.Create procedure with the validation code
SQL to validate your constraint will look something like:
SELECT *
FROM yourtable yt
WHERE yt.id = NEW.id -- replace with arguments passed to procedure
AND yt.A = NEW.A -- same as above
You most likely need to wrap it up with an EXISTS statement and if statement
Some source of knowledge:
Trigger Syntax and Examples
Create Procedure Syntax
I wanted to make a trigger which updates a table with the values of a procedure. I want the trigger to do something like this:
DELIMITER $$
CREATE TRIGGER onInsertVillage AFTER INSERT ON Village
FOR EACH ROW
BEGIN
UPDATE Village V SET V.xCoordinaat = x, V.yCoordinaat = y FROM getVrijePlaatsInMap();
END$$
DELIMITER ;
But this doesn't work.. The procedure returns an x and y value by the way. Is there a possible way to make the trigger do it's job?
I suppose that the trigger shall adapt xCoordinaat and yCoordinat for every new village inserted into table Village. If this is the case, I would use an BEFORE INSERT-trigger, which has access to the values of the respective village record to be inserted (before it is inserted). In absence of schema and stored procedure code of your example, I wrote a simplified program demonstrating this approach:
create table test (
a int,
b int,
c int
);
CREATE PROCEDURE simpleproc (IN a int, OUT b INT, OUT c int)
BEGIN
set b = a div 100;
set c = a % 100;
END;
CREATE TRIGGER test_before_insert
BEFORE INSERT
ON test FOR EACH ROW
BEGIN
call simpleproc (new.a,new.b,new.c);
END;
insert into test (a,b,c) values (120,0,0), (210,0,0), (303,0,0);
this yields:
a | b | c
----|---|---
120 | 1 | 20
210 | 2 | 10
303 | 3 | 3
Getting your approach working might be a little bit more tricky; In an AFTER INSERT-trigger, you have access to the .NEW-values, but you cannot modify them; Hence, you have to do an update on the table, but you somehow have to identify the village that has just been inserted.
I need some help on creating a trigger on MySQL.
I have a table "comment":
id_comment | id_topic | comment
and the "topic" table:
id_topic | topic | comments_ammount
I need to increase comments_ammount for each insert on "comment" table which has the same id_topic of the topic.
I never used triggers, so anyone can help me?
well ,i am not special in mysql but i think you can do something like this
DELIMITER $$
declare #x table(id_topic int)
insert into #x '#x hold last insert'
select *
from comment
order by id desc
limit 1
update topic t join #x c
on c.id_topic =t.id_topic
set comments_ammount=comments_ammount+1
DELIMITER $$
DELIMITER ;