Как прервать операцию INSERT в триггере MySql? - PullRequest
31 голосов
/ 29 марта 2010

У меня есть таблица, содержащая URL-адрес и строку, представляющую его параметры. Проблема в том, что я хочу, чтобы URL и строка параметров были уникальным ограничением для таблицы - иначе записи не могут иметь одинаковую строку URL-адреса И параметра. Строка параметра может иметь произвольную длину (более 800 байт или около того, что является максимальной длиной ключа MySql, поэтому я не могу использовать Unique (url, params), поскольку он выдает ошибку ...).

Я думал об использовании триггеров для этого, но как вывести исключение / вызвать ошибку, если триггер обнаруживает, что вставка собирается вставить повторяющуюся запись? Я предполагаю, что хотел бы, чтобы MySqlException выдавал, как MySql, с дублированными первичными ключами и т. Д., Чтобы я мог перехватить его в своем коде C #.

У меня есть две части в триггере, с которыми мне нужно получить помощь: ... Прервать выбрасывание исключения в C # ... Как мне вывести исключение и т.д. в C #? ... Разрешить вставку ... - как разрешить вставку, если нет повторяющейся записи?

Вот код триггера:

CREATE TRIGGER urls_check_duplicates
BEFORE INSERT ON urls
FOR EACH ROW

BEGIN
DECLARE num_rows INTEGER;

SELECT COUNT(*)
INTO num_rows
FROM urls
WHERE url = NEW.url AND params = NEW.params;

IF num_rows > 0 THEN
   ... ABORT/throw exception to C# ...
ELSE
   ... Allow insert ...
END

Ответы [ 3 ]

70 голосов
/ 19 декабря 2011

Я сталкивался с этим, и хотя решение работает, позже я наткнулся на то, что мне кажется лучшим решением. Я подозреваю, что это был не вариант, когда на этот вопрос изначально был дан ответ.

CREATE TRIGGER `TestTable_SomeTrigger`
BEFORE UPDATE ON `test_table`
FOR EACH ROW
BEGIN
    DECLARE msg VARCHAR(255);
    IF (SomeTestToFail = "FAIL!") THEN
        set msg = "DIE: You broke the rules... I will now Smite you, hold still...";
        SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = msg;
    END IF;

    -- Do any other code here you may want to occur if it's all OK or leave blank it will be
    --  skipped if the above if is true
END$$

Теперь будет возвращено приятное (или злое!) Сообщение об ошибке, которое вы можете перехватить. Для получения дополнительной информации об этом см .: http://dev.mysql.com/doc/refman/5.5/en/signal.html

Надеюсь, это поможет кому-то еще!

8 голосов
/ 29 марта 2010

Комментарии в документации mysql о триггерах предполагают, что в mysql такой функции нет. Лучшее, что вы можете сделать, - это создать отдельную таблицу для ваших ошибок триггера, , как предлагается на той же странице .

6 голосов
/ 17 ноября 2010

Если ваше определение таблицы для значения NOT NULL, вы можете установить NEW в NULL, что фактически не будет выполнять вставку. Возможно, вам придется включить строгий режим sql для правильной работы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...