I have a MYSQL table named procurement with the following columns...
| id | province | sample_result | image | status |
| 1 | prov_1 | 3 | url | Complete |
| 2 | prov_2 | 12 | NULL | |
| 3 | prov_3 | 45 | NULL | |
| 4 | prov_4 | | url | |
I would like to create a TRIGGER that updates the column "status" with "Complete" when both the sample_result and image columns are updated and no longer NULL. If either one is NULL then no update is required.
You can set NEW. values in a before trigger and since mysql copies OLD. values to NEW. values before it acquires NEW. values from the update then testing NEW. values is safe
drop table if exists t;
create table t
( id int, province varchar(10), sample_result int, image varchar(10), status varchar(10));
insert into t values
( 1 , 'prov_1' , 3 , 'url' , 'Complete'),
( 2 , 'prov_2' , 12 , NULL , null ),
( 3 , 'prov_3' , 45 , NULL , null ),
( 4 , 'prov_4' , null , 'url' , null );
drop trigger if exists t;
delimiter $$
create trigger t before update on t
for each row
begin
if new.sample_result is not null and new.image is not null then
set new.status = 'Complete';
end if ;
end $$
delimiter ;
update t set sample_result = 2 where id = 2;
update t set sample_result = 1 where id = 4;
update t set image = 'url' where id = 3;
select * from t;
+------+----------+---------------+-------+----------+
| id | province | sample_result | image | status |
+------+----------+---------------+-------+----------+
| 1 | prov_1 | 3 | url | Complete |
| 2 | prov_2 | 2 | NULL | NULL |
| 3 | prov_3 | 45 | url | Complete |
| 4 | prov_4 | 1 | url | Complete |
+------+----------+---------------+-------+----------+
Related
I am using mysql 8.0.30.
I have an orders table which is defined as follows:
create table orders (
id INT AUTO_INCREMENT NOT NULL PRIMARY KEY,
code varchar (64) NOT NULL,
ord_num varchar(512) NOT NULL );
After inserting a rows, I would like to have it as follows:
+----+------+-------+
| id | code | ord_num|
+----+------+-------+
| 1 | abc | abc-1 |
| 2 | def | def-2 |
+----+------+-------+
That is ord_num should have concatenation of code-id. I can achieve that by an update statement as follows:
update orders set ord_num = concat (code, '-', id ) where id = 2;
However, I would like to achieve that in the insert statemenet. For ex:
insert into orders (code, ord_num) values ("xyz", concat(code, '-', id));
This actually results in:
+----+------+-----------+
| id | code | ord_num |
+----+------+-----------+
| 1 | abc | abc-0 |
| 2 | def | def-2 |
| 3 | xyz | xyz-0 |
+----+------+-----------+
I know I can do this by starting a transaction, insert with some dummy value in ord_num, then updating it with the correct value before committing. I would prefer to do it in one insert statement, if possible?
Do not judge strictly, but I can not figure it out in any way
My table:
CREATE table courses (id INT PRIMARY KEY AUTO_INCREMENT,
-> faculty VARCHAR(55) NULL,
-> number INT(10) NULL,
-> diff VARCHAR(10) NULL);
mysql> select * from courses;
Target. Inject values ('ez', 'mid', 'hard') into diff column.
For exampl, im trying this:
mysql> INSERT courses (diff) VALUES ('ez');
OR
mysql> UPDATE courses SET faculty = 'chem', number = 2, diff = 'mid';
Add rows with empty id(values NULL).
PLZ help me!
I want to get this result
+----+---------+--------+------+
| id | faculty | number | diff |
+----+---------+--------+------+
| 1 | bio | 1 | ez |
| 2 | chem | 2 | mid |
| 3 | math | 3 | hard |
| 4 | geo | 4 | mid |
| 5 | gum | 5 | ez |
+----+---------+--------+------+
You can use a case expression in an UPDATE statements:
UPDATE courses
SET diff=CASE
WHEN faculty in ('bio', 'gum') THEN 'ez'
WHEN faculty in ('chem', 'geo') THEN 'mid'
WHEN faculty = 'math' THEN 'hard'
END;
I have tables products and column_names as follows:
products
+----+------+-----------+--------------+-------+
| id | code | category | description | link |
+----+------+-----------+--------------+-------+
| 1 | 1111 | category1 | description1 | link1 |
| 2 | 2222 | category1 | description2 | link2 |
| 3 | 3333 | category1 | description3 | link3 |
| 4 | 4444 | category2 | description4 | link4 |
| 5 | 5555 | category2 | description5 | link5 |
| 6 | 6666 | category3 | description6 | link6 |
+----+------+-----------+--------------+-------+
column_names
+----+-------------+-------+
| id | column | type |
+----+-------------+-------+
| 1 | id | type1 |
| 2 | code | type1 |
| 3 | category | type2 |
| 4 | description | type2 |
| 5 | link | type3 |
+----+-------------+-------+
I can make this statement:
SELECT ( SELECT `column` FROM `column_names` WHERE `column_id` = 3) FROM `products` WHERE `id` = 1
while I cannot get this statement:
SELECT ( SELECT `column` FROM `column_names` WHERE `type` = 'type2') FROM `products` WHERE `id` = 1
It gives me error #1242 - Subquery returns more than 1 row
But is it possible to perform query like that? Namely, I would like to extract data just of certain columns in the products table that have certain type in the column_names table.
Is this the right design of the tables or should there be another approach? Of course category should be in another table but this is not what I am asking.
Thank you very much!
So, thanks to Gordon Linoff and A Paul I was able to do what I wanted. I know this is probably a clumsy solution but it works. Anyone who would like to point out clumsiness is welcome.
So, first I created a user defined procedure GetMyColumns(). I cannot tell the exact purpose of the first two lines. It is just what the phpMyAdmin editor for functions added when I chose option in the editor.
DELIMITER $$
CREATE DEFINER=`geonextp`#`localhost` FUNCTION `GetMyColumns`(`type` VARCHAR(258)) RETURNS VARCHAR(4096) CHARSET latin1 NOT DETERMINISTIC READS SQL DATA SQL SECURITY DEFINER BEGIN
DECLARE rownum INT DEFAULT 1;
DECLARE counter INT DEFAULT 1;
DECLARE columns_string VARCHAR(4096) DEFAULT '';
DECLARE col_string VARCHAR(512);
SET rownum = (SELECT COUNT(*) FROM column_names);
SET columns_string = '';
WHILE counter <= rownum DO
SET col_string = (
SELECT `column_name`
FROM `column_names`
WHERE
`column_id` = counter AND
`column_type` = type
);
IF col_string IS NULL
THEN
SET col_string = '';
END IF;
IF columns_string = '' THEN
SET columns_string = col_string;
ELSE
IF NOT (col_string = '')
THEN
SET columns_string = CONCAT(CONCAT(columns_string, ', '), col_string);
END IF;
END IF;
SET counter = counter + 1;
END WHILE;
RETURN columns_string;
END$$
DELIMITER ;
Then I added a little piece of code A Paul suggested:
SET #inner_sql = GetColumns('type2');
SET #sql = CONCAT(CONCAT('SELECT ', #inner_sql), ' FROM products WHERE id = 1');
PREPARE stmt FROM #sql;
EXECUTE stmt;
The result is exactly:
+-----------+--------------+
| category | description |
+-----------+--------------+
| category1 | description1 |
+-----------+--------------+
It's been an experience :)
I have two tables, but I would like to set a trigger. When I insert a new user to my table users, I would like to copy that id to another table: results.
Table users:
| userID | name | email | password |
+--------+----------+-------------------+----------+
| 1 | Person A | mailA#gmail.com | 12345 |
+--------+----------+-------------------+----------+
| 2 | Person B | mailB#yahoo.com | 13579 |
+--------+----------+-------------------+----------+
| 3 | Person C | mailC#outlook.com | 24681 |
+--------+----------+-------------------+----------+
Table results:
| resultID | userID | TestA | TestB |
+----------+--------+-------+-------+
| 162 | 1 | 84 | 63 |
+----------+--------+-------+-------+
| 028 | 2 | NULL | 54 |
+----------+--------+-------+-------+
| 821 | 3 | 77 | 60 |
+----------+--------+-------+-------+
I would like to copy the userID from table users to userID in table results after insert.
I tried various options with triggers, but nothing fixed my problems.
One of them is:
CREATE TRIGGER T_TableA_I
on users
after insert
as
set nocount on
insert into results (userID)
select u.UserID
from
users u
inner join
results r
on
u.UserID = r.UserID
It may be that my structure is not in accordance with the guidelines, but this is a concept.
I am still not sure if I understand the question but here's a code snippet for conversation
drop table if exists us,res;
create table us (id int);
create table res (id int);
drop trigger if exists t;
delimiter $$
create trigger t after insert on us
for each row
begin
insert into res(id) values (new.id);
end $$
delimiter ;
insert into us values (1);
select * from us;
+------+
| id |
+------+
| 1 |
+------+
1 row in set (0.00 sec)
select * from res;
+------+
| id |
+------+
| 1 |
+------+
1 row in set (0.00 sec)
I have written the following code snippet, but I could not figure out where to get the test result!
CREATE TABLE IF NOT EXISTS users (
userID INT(6) UNSIGNED PRIMARY KEY,
name VARCHAR(255),
password VARCHAR(255),
email VARCHAR(255)
);
CREATE TABLE IF NOT EXISTS results (
resultID INT(6) UNSIGNED PRIMARY KEY,
userID VARCHAR(255),
TestA VARCHAR(255),
TestB VARCHAR(255)
);
/* trigger query */
CREATE TRIGGER new_user_added
AFTER INSERT ON users
FOR EACH ROW
INSERT INTO results values('162', NEW.userID, '84', '63');
/* insert query */
replace into users values('1', 'Person A', 'mailA#gmail.com', '12345');
select * from users;
select * from results
users
| userID | name | email | password |
+--------+----------+-------------------+----------+
| 1 | Person A | mailA#gmail.com | 12345 |
+--------+----------+-------------------+----------+
results
| resultID | userID | TestA | TestB |
+----------+--------+-------+-------+
| 162 | 1 | 84 | 63 |
+----------+--------+-------+-------+
Hope this could help.
I have SET data type field in Mysql table, which contains values SET('dog','cat','hamster'). I would like to update value 'dog' into 'puppy' and as well change values in all records from 'dog' into 'puppy'. Thank you.
Use these three query's:
ALTER TABLE `table `CHANGE `field` `field` SET ('dog','cat','hamster', 'puppy' );
update table `table` set `field` ='puppy' where `field`='dog';
ALTER TABLE `table `CHANGE `field` `field` SET ('cat','hamster', 'puppy' );
The answer provided by Jens will work only when field has values 'dog' and nothing else. But this one is SET and not ENUM. Thus it can have field with multiple values which also includes 'dog'. For example - 'dog,cat', 'dog,hamster', 'dog,cat,hamster'. In such cases this answer won't work. Also here CHANGE is unnecessary and MODIFY will suffice. I have provided the code below which will work in any scenario -
CREATE TABLE my_table (
-> id INT UNSIGNED NOT NULL AUTO_INCREMENT,
-> animal SET("dog","cat","hamster"),
-> PRIMARY KEY (id)
-> );
INSERT INTO my_table (animal) VALUES ("dog");
INSERT INTO my_table (animal) VALUES ("dog,cat");
INSERT INTO my_table (animal) VALUES ("dog,hamster");
INSERT INTO my_table (animal) VALUES ("dog,cat,hamster");
SELECT * FROM my_table;
+----+-----------------+
| id | animal |
+----+-----------------+
| 1 | dog |
| 2 | dog,cat |
| 3 | dog,hamster |
| 4 | dog,cat,hamster |
+----+-----------------+
ALTER TABLE my_table
-> MODIFY animal SET (
-> "dog","cat","hamster","puppy");
DESCRIBE my_table;
+--------+------------------------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------+------------------------------------+------+-----+---------+----------------+
| id | int unsigned | NO | PRI | NULL | auto_increment |
| animal | set('dog','cat','hamster','puppy') | YES | | NULL | |
+--------+------------------------------------+------+-----+---------+----------------+
UPDATE my_table
-> set animal = CASE
-> WHEN animal LIKE "dog"
-> THEN REPLACE(animal,"dog","puppy")
-> WHEN animal LIKE "dog%"
-> THEN REPLACE(animal,"dog,","puppy,")
-> WHEN animal LIKE "%dog%"
-> THEN REPLACE(animal,",dog",",puppy")
-> ELSE animal
-> END;
SELECT * FROM my_table;
+----+-------------------+
| id | animal |
+----+-------------------+
| 1 | puppy |
| 2 | cat,puppy |
| 3 | hamster,puppy |
| 4 | cat,hamster,puppy |
+----+-------------------+
ALTER TABLE my_table
-> MODIFY animal SET("cat","hamster","puppy");
DESCRIBE my_table;
+--------+------------------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------+------------------------------+------+-----+---------+----------------+
| id | int unsigned | NO | PRI | NULL | auto_increment |
| animal | set('cat','hamster','puppy') | YES | | NULL | |
+--------+------------------------------+------+-----+---------+----------------+
The original credit goes to #Jens though.