2014-04-29 3 views
0

У меня есть этот триггерMysql ошибка синтаксиса с триггером

CREATE TRIGGER checkcollision AFTER UPDATE ON players BEGIN 
    SELECT RAISE(ABORT, 'collision') FROM walls WHERE NEW.x=x AND NEW.y=y; 
END; 

MySQL 5.1.72-0ubuntu0.10.04.1 (Ubuntu)

Но я получаю ошибку синтаксиса, и я не вижу где ...

EDIT:

DELIMITER // 
CREATE TRIGGER checkcollision AFTER UPDATE ON players BEGIN SELECT RAISE(ABORT, 'collision') FROM walls WHERE NEW.x=x AND NEW.y=y; END// 
DELIMITER ; 

Это все еще получаю синтаксическую ошибку ...

enter image description here

Это получаю ошибку синтаксиса:

DELIMITER // 
CREATE TRIGGER checkcollision AFTER UPDATE ON players 
    FOR EACH ROW 
    BEGIN 
     IF (SELECT count(*) FROM walls WHERE NEW.x=x AND NEW.y=y)>0 THEN 
      SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Collision detected'; 
     END IF; 
    END;// 
DELIMITER ; 

enter image description here

+0

Возможно, вы не изменили 'DELIMITER'. –

+0

Как это сделать? – omega

+0

@omega: опубликовано сообщение об ошибке синтаксиса. Разве что, мы тоже не видим, где ... !!! ??? –

ответ

0

Вы, вероятно, не изменился DELIMITER

How do I do that?

С помощью команды DELIMITER, описанные здесь

Это важно, чтобы изменить разделитель, когда вы создаете триггера или процедуры, так как в противном случае с помощью точки с запятой заявление разделителя внутри тела вашего триггера (например, в конце инструкции SELECT) является неоднозначным относительно точки с запятой в конце инструкции CREATE TRIGGER.

Это очень распространенный источник путаницы для разработчиков MySQL.

+0

ok Я добавил свой новый код выше с помощью delimeter, но его все еще получаю синтаксическую ошибку. – omega

0

Edit 1:

How do I get it to roll back the change if there is a collision then

Rollback, commit не допускаются в триггерах.
Вместо этого вы можете поднять signal, установив sqlstate при неисправности состояния.

IF (condition_for_collision_true) THEN 
    SET error_message = 'Invalid XYZ'; -- set proper message 

    -- set proper error state number 
    SIGNAL SQLSTATE <ERROR_STATE_NUMBER> SET message_text = error_message; 
END IF; 

Это приводит к прерыванию транзакции.


Оригинальный ответ:

Триггеры уволят для каждой строки пострадавших.

И у вас отсутствует то же самое в определении триггера.

DELIMITER // 

CREATE TRIGGER checkcollision 
     AFTER UPDATE ON players 
     FOR EACH ROW 
BEGIN 
    SELECT RAISE(ABORT, 'collision') FROM walls WHERE NEW.x=x AND NEW.y=y; 
END; 

// 

DELIMITER ; 

И, это очевидно. Триггеры не являются обычными процедурами. Они предназначены для фоновых действий. Вы не можете ожидать, что они вернут курсор или любой другой результат. Но выполните действие, подобное настройке или сбросу значения в строке или любой операции DML в другой связанной таблице и т. Д.

Измените корпус соответствующим образом.

+0

Делает это с помощью mysql 5.1, я не думаю, что это так. – omega

+0

Да. Условный аборт транзакции возможен только с 'MySQL 5.5'. Предлагается взломать [* здесь *] (http://dev.mysql.com/doc/refman/5.1/en/create-trigger.html#c8808). –

Смежные вопросы