Conditional values in MySQL Trigger - mysql

I have a question about MySQL triggers—say I have the following table:
CREATE TABLE test (
id INT(6),
value_1 INT(6),
value_2 INT(6),
values_were_set BOOL
)
Now, every time I insert a value into this table I want to have a trigger check if value_1 and value_2 have been set. And if they are, it should set values_were_set to true.
NULL values are allowed.
How would I go about this? In the real table there are about ten columns that I want to check for, so I would fancy not to have to use a bunch of IF statements.
Maybe it's better to do it in the app?

Then trigger it is:
DELIMITER $$
CREATE TRIGGER value_check BEFORE INSERT ON test
FOR EACH ROW
BEGIN
IF NEW.value_1 IS NOT NULL AND NEW.value_2 IS NOT NULL THEN
SET NEW.values_were_set = 1;
ELSE
SET NEW.values_were_set = 0;
END IF;
END;
$$
Unfortunately yes, I think you would need a nasty if/else section in the trigger if you want to check multiple combinations of fields

Related

stored procedure returning `ASCII \0` error but can't find what that is referring to

I am writing my first stored procedure as a trigger. I am doing this in a dev migration as we have two systems which don't speak to each other in dev, so I need to mock the data which would normally come from the other system.
My procedure is added as part of our dev migration script.
DELIMITER |;
CREATE TRIGGER `activity_insert` AFTER INSERT ON `activity`
FOR EACH ROW
BEGIN
UPDATE `activity` AS `a` JOIN `handle` AS `h` on `a.handle_id` = `h.handle_id` SET `path` = CONCAT(`h.handle`,'/',`a.activity_handle`) WHERE `a.path` IS NULL;
END;
|
DELIMITER;
I would expect the logic to be:
DELIMITER $$
CREATE TRIGGER activity_insert BEFORE INSERT ON activity
FOR EACH ROW
BEGIN
IF new.path IS NULL THEN
SET new.path = (SELECT CONCAT(h.handle, '/', new.activity_handle)
FROM handle h
WHERE new.handle_id = h.handle_id
);
END IF;
END;$$
DELIMITER;
There are numerous problem with your code:
You don't update the table being modified using update.
You want a "before" triggers, not an "after trigger".
Don't use | for the the delimited. It is a valid MySQL operator.
You have over-used the backtick, including putting the table alias in with the column alias.
This assumes that handle.handle_id is unique. This seems like a reasonable assumption based on the names, but you can add limit 1 to guarantee no more than one row is returned.

MySQL Column Update with trigger

I have this reservation table that has RESERVATION_ID , ROOM_NUM, Date_Start , Date_End and cost columns. what I want to do is insert all the columns except cost and fill the cost automatically.
delimiter //
CREATE TRIGGER upd_check before INSERT ON reservation
FOR EACH ROW
BEGIN
IF NEW.RESERVATION_COST = NULL THEN
SET NEW.RESERVATION_COST = 'timestampdiff(day, NEW.RESERVATION_STARTD, NEW.RESERVATION_ENDD)*70';
END IF;
END;//
delimiter ;
I wrote this trigger to do it, but whenever I press Apply to insert everything nothing is inserted to the RESERVATION_COST column.
why?
I would put this in a comment if I had enough reputation, but anyways. Triggers cannot act on the same table which activated them. Seems limiting, but we've had the same issue.
This link doesn't explicitly say this but it does say "in the associated table". Not the same: https://dev.mysql.com/doc/refman/5.0/en/triggers.html
You can't compare a value to NULL, you need to check if it IS NULL instead.
e.g.
IF NEW.RESERVATION_COST IS NULL THEN

Creating a trigger that insert something if

I need a bit of help with creating a trigger in mysql:
I have a column named “country” and another one named “tag”.
Everytime when someone insert in the city “Los Angeles” for example, I want that my trigger to insert in “tag” column the text “is from California”.
Edit:
delimiter //
CREATE TRIGGER update_tag AFTER UPDATE ON users
FOR EACH ROW
BEGIN
IF (city = 'Los Angeles') THEN
INSERT INTO users(tag) VALUES (California);
END IF;
END;//
delimiter ;
That seems to be executed with no errors, but is not inserting anything in "tag" column,
Any ideea why?
PS. I would appreciate from the ones that rated this post with "-" to write me a PM and tell me what I did wrong :). Thank you.
You cannot use an insert statement to update the row you are currently processing. You should use the SET NEW.cxy = "" syntax.
I have prepared a working sqlfiddle for you, which hopefully shows want you wanted to achieve.
CREATE TABLE users (
id int auto_increment PRIMARY KEY,
`city` varchar(255),
`tag` varchar(255)
)//
CREATE TRIGGER update_tag BEFORE UPDATE ON users
FOR EACH ROW
BEGIN
IF (NEW.city = 'Los Angeles') THEN
SET NEW.tag = "California";
END IF;
END//
INSERT INTO users VALUES (1, 'test', '')//
UPDATE users SET `city` = 'Los Angeles'//
Please notice that this is also a BEFORE UPDATE trigger, so that your changes are saved as well.
If one issues a SELECT * FROM users one receives a single row with
1 Los Angeles California
There is also a page in the MySQL manual containing trigger examples. You should read that thoroughly.

MySQL: Set to default value on update

Is it possible to set a column to its default value (or any specified value) on update when no value is specifically given in the statement? I was thinking that a trigger might accomplish this. Something like
IF ISNULL(NEW.column) THEN
NEW.column = value
END IF;
didn't work.
MySQL has function called DEFAULT(), which gets the default value from specified column.
UPDATE tbl SET col = DEFAULT(col);
MySQL Reference
UPDATE:
#JanTraenkner As far as I can tell, this is not possible. You can however make sure in your application code, that all columns are mentioned in your update statement and for those that do not have a value your use NULL as value. Then your trigger code is almost right, you just need to change it to
IF (NEW.column IS NULL) THEN
SET NEW.column = value
END IF;
Original answer:
I understood your question like, "set column to default value, if I don't specify the column in an update statement (which updates other columns from that table)".
To check with ISNULL() or col IS NULL doesn't work here, because when you don't specify it in the update statement it simply isn't there. There's nothing to check for.
I wrote this little example script which makes it work like I understood the question.
drop table if exists defvalue;
create table defvalue (id int auto_increment primary key, abc varchar(255) default 'default');
insert into defvalue (id) values (null);
insert into defvalue (id, abc) values (null, 'not_default_value');
insert into defvalue (id, abc) values (null, 'another_not_default_value');
drop trigger if exists t_defval;
delimiter $$
create trigger t_defval before update on defvalue
for each row
begin
set #my_def_value = (select default(abc) from defvalue limit 1);
if (new.abc = old.abc) then
set new.abc = #my_def_value;
end if;
end $$
delimiter ;
select * from defvalue;
update defvalue set id = 99 where id = 1;
select * from defvalue;
update defvalue set id = 98 where id = 2;
select * from defvalue;
I also had to save the default value of the column in a variable first because the function needs to know from which table. Unfortunately one can't specify that as parameter, not even as default(tablename.column).
All in all, please note, that this is rather a proof of concept. I'd recommend to solve this on application layer, not database layer. Having a trigger for this seems a bit dirty for me.

set maximum value to a column

I have a table with a column (int type) called age. This column should hold maximun value 50. If it exceeds then it shouldn't update that row.
Means this column shold take values from 0 to 50.
If I try to update that to 51 then that shouldn't allow.
Could any one help....!
Try this:
CREATE TRIGGER check_trigger
BEFORE INSERT
ON table
FOR EACH ROW
BEGIN
IF NEW.age<0 OR NEW.age>50 THEN
CALL `Error: Wrong values for age`; -- this trick will throw an error
END IF;
END
create table test (
age tinyint not null ) engine = myisam;
delimiter //
drop trigger if exists max_num//
create trigger max_num before insert on test
for each row
begin
if new.age < 0 or new.age > 50 then
set new.age = null;
end if;
end//
delimiter ;
insert into test (age) values (100);
Make the same thing for update.
You could use CHECK constraint:
CREATE TABLE person (
Name VARCHAR(80),
Age INT CHECK (Age BETWEEN 5 and 50));
MySQL introduced check constraints in MySQL 8.0.16 and now the check constraints are enforced as you would reasonably expect.
See MySQL 8.0.16 introduced check constraints.
So, you can achieve your goal by altering your age column using the statement below.
ALTER TABLE `YOUR_TABLE_NAME` MODIFY `age` TINYINT(2) UNSIGNED NOT NULL DEFAULT 0 CHECK(`age` <= 50);