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.