Reputation: 6809
I am developing a program that uses a MySQL database to store data. I have a table (simplified here):
+---------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------+------------------+------+-----+---------+----------------+
| dataId | int(10) unsigned | NO | PRI | NULL | auto_increment |
| someNum | tinyint(4) | NO | | 0 | |
+---------+------------------+------+-----+---------+----------------+
Now, I update the table with a query like this one.
UPDATE table SET someNum=someNum+2 WHERE dataId=78225;
The ID and the amount someNum
changes come dynamically from code.
Now, what I'd like to do is limit someNum
's value to between -3 and 3, particularly in that UPDATE
. It isn't required, my software can handle it being outside that range, but the data would be clearer with that limit. If someNum+2
would be over 3, I'd just like to set it to 3.
Numeric MIN
/MAX
would make it easy:
UPDATE table SET someNum=MAX(-3,MIN(3,someNum+2)) WHERE dataId=78225;
I looked at the docs here, but there seems to be no MIN
/MAX
for numbers. MIN
and MAX
are found here, but they don't seem to be the right ones for this.
What would be the best way (if any) to implement such a limit in MySQL (not the code that calls MySQL)?
Upvotes: 0
Views: 119
Reputation: 37365
First way: use LEAST()
and GREATEST()
:
UPDATE t SET someNum=GREATEST(-3,LEAST(3,someNum+2)) WHERE dataId=78225;
This is the most easy way because you'll store all the logic inside one UPDATE
query.
Second way: create trigger:
DELIMITER //
CREATE TRIGGER catCheck BEFORE UPDATE ON t
FOR EACH ROW
BEGIN
IF NEW.someNum<-3 THEN
NEW.someNum=-3;
END IF;
IF NEW.someNum>3 THEN
NEW.someNum=3;
END IF;
END;//
DELIMITER ;
you can also replace IF
with CASE
- but I left that two separate constraints for -3
and 3
. The benefits here is - that DBMS will handle your data by itself - and you'll be able to pass data as it is and do not worry about ranges. But - there's weakness too: while in first case you can just change query text to adjust desired range, in second case you'll have to re-create trigger again if you'll want to change that constraints (so, less flexibility).
Also you may want to check your data not only on UPDATE
statements, but on INSERT
too.
Upvotes: 2
Reputation: 60493
use GREATEST and LEAST instead of MAX and MIN
You could also use a CASE WHEN
update table
set someNum = CASE WHEN SomeNum +2 > 3 THEN 3
WHEN SomeNum +2 < -3 THEN -3
ELSE someNum + 2
END)
Upvotes: 1
Reputation: 1269623
The appropriate functions in MySQL are greatest()
and least()
, not max()
/min()
. But, I think it is clearer with just a case
statement:
UPDATE table
SET someNum = (case when someNum + 2 < -3 then -3
when someNum + 2 > 3 then 3
else someNum + 2
end)
WHERE dataId=78225;
Upvotes: 1