How do I get MySQL to throw a conditional runtime exception in SQL
You can raise an exception without function / procedure by simply running a subquery returning MORE THAN ONE row but EXPECTING ONLY ONE row. Usually in a database there is a table for that already, but here I included a table for that purpose:
create table t (a int);
insert into t values(1);
insert into t values(1);
select * from t;
The below select raises exception because the outer select EXPECTS one value BUT the inner select returns MORE THAN ONE value.
select (select a from t);
You can apply that for your case:
select case when
2*2 = 4
then 'OK'
else (select a from t)
end;
select case when
2*2 = 5
then 'OK'
else (select a from t)
end;
See also: https://dba.stackexchange.com/questions/78594/how-to-conditionally-raise-an-error-in-mysql-without-stored-procedure
It cannot be done without a stored procedure or function, unfortunately. I figured out how to support a function in my app, though. Borrowing the basic procedure idea from this answer, I've come up with this:
DELIMITER |
CREATE FUNCTION checkit(doit INTEGER, message VARCHAR(256)) RETURNS INTEGER DETERMINISTIC
BEGIN
IF doit IS NULL OR doit = 0 THEN
SIGNAL SQLSTATE 'ERR0R' SET MESSAGE_TEXT = message;
END IF;
RETURN doit;
END;
|
The idea is that the function can be used in triggers like a CHECK
constraint, or inline in SQL statements. Getting back to my original need to throw an error if a user does not exist, I now use the checkit()
function like this:
SELECT checkit(COUNT(*), 'User "foo" does not exist')
FROM mysql.user WHERE user = 'foo';
If user foo
exists, this query returns an integer. If the user does not exist, it throws an error with the message defined there.
Want to use the function for a check constraint, too? He's an example (mimicking this answer), with a tip of the hat to @rouland-bouman:
CREATE TRIGGER mytabletriggerexample BEFORE INSERT FOR EACH ROW
BEGIN
SET @dummy := checkit(
NEW.important_value) >= (fancy * dancy * calculation),
'Your meaningful error message goes here'
);
END;
I would rather use DO
, rather than setting a dummy variable, but a MySQL bug prevents that from working, alas.