К сожалению, ответ, предоставленный @RuiDC, не работает в версиях MySQL до 5.5, потому что не существует реализации SIGNAL для хранимых процедур.
Решение, которое я нашел , состоит в том, чтобы имитировать сигнал, выдающий ошибку table_name doesn't exist
, помещая настроенное сообщение об ошибке в table_name
.
Взлом может быть реализован с помощью триггеров или с помощью хранимой процедуры. Я опишу оба варианта ниже, следуя примеру, используемому @ RuiDC.
Использование триггеров
DELIMITER $$
-- before inserting new id
DROP TRIGGER IF EXISTS before_insert_id$$
CREATE TRIGGER before_insert_id
BEFORE INSERT ON test FOR EACH ROW
BEGIN
-- condition to check
IF NEW.id < 0 THEN
-- hack to solve absence of SIGNAL/prepared statements in triggers
UPDATE `Error: invalid_id_test` SET x=1;
END IF;
END$$
DELIMITER ;
Использование хранимой процедуры
Хранимые процедуры позволяют использовать динамический sql, что делает возможным инкапсуляцию функциональности генерации ошибок в одной процедуре. Конечным моментом является то, что мы должны контролировать методы вставки / обновления приложений, чтобы они использовали только нашу хранимую процедуру (не предоставляя прямые привилегии INSERT / UPDATE).
DELIMITER $$
-- my_signal procedure
CREATE PROCEDURE `my_signal`(in_errortext VARCHAR(255))
BEGIN
SET @sql=CONCAT('UPDATE `', in_errortext, '` SET x=1');
PREPARE my_signal_stmt FROM @sql;
EXECUTE my_signal_stmt;
DEALLOCATE PREPARE my_signal_stmt;
END$$
CREATE PROCEDURE insert_test(p_id INT)
BEGIN
IF NEW.id < 0 THEN
CALL my_signal('Error: invalid_id_test; Id must be a positive integer');
ELSE
INSERT INTO test (id) VALUES (p_id);
END IF;
END$$
DELIMITER ;