The immediate issue with your first statement is that it has BEGIN without a corresponding END. In this case, END should be at the very end of the CREATE TRIGGER statement.
Once you add the END keyword, the statement becomes technically correct, but you will have trouble executing it in MySQL. The reason is that semicolons, while being standard statement delimiters in SQL, are also treated by MySQL in a special way. MySQL splits the input text at semicolons and sends each part of the text to the server separately. The server thus receives incomplete, syntactically incorrect pieces and returns an error. See here for more details:
So, to prevent MySQL from doing that, you need to instruct it to use a different symbol as a delimiter – that is what the DELIMITER command is for. Consequently, your second attempt should be something like this:
DELIMITER $$
CREATE TRIGGER `estatecat_piece`
AFTER INSERT ON `estate`
FOR EACH ROW
BEGIN
UPDATE estate_category set piece = (Select count(*) from estate where estate.estatecat_id=new.estatecat_id);
END$$
DELIMITER ;
The first DELIMITER command tells MySQL to parse the input text until $$
is encountered from that point on. Your CREATE TRIGGER should, therefore, end with the $$
symbol so that MySQL can consume it in its entirety and send the whole statement to the server. Finally, the second DELIMITER command restores the standard delimiter for MySQL to resume normal processing of your commands.
There is also a simpler solution, but it works only in cases similar to yours. The trigger body in your case consists of a single statement. That allows you to omit the keywords BEGIN and END from your statement and, as a result, avoid using the DELIMITER command at all:
CREATE TRIGGER `estatecat_piece`
AFTER INSERT ON `estate`
FOR EACH ROW
UPDATE estate_category set piece = (Select count(*) from estate where estate.estatecat_id=new.estatecat_id);
The above trigger will work exactly the same.
On a different note, your UPDATE statement may have a flaw: as currently written, it will update the piece
column in every row with the same row count – that of the category matching the inserted row. If the table has multiple rows, each for a different category, you probably need to introduce a filter on new.estatecat_id
to your UPDATE statement, similar to the filter in the subquery, in order to update only the corresponding piece
value:
UPDATE
estate_category
SET
piece = (
SELECT
COUNT(*)
FROM
estate
WHERE
estate.estatecat_id=new.estatecat_id
)
WHERE
... /* specify the necessary column name */ = new.estatecat_id
;
The host
, user
, and password
values are supposed to be enclosed in single quotes.
You are also better off executing it as Dynamic SQL
DELIMITER //
DROP PROCEDURE IF EXISTS changeMasterTo //
CREATE PROCEDUREchangeMasterTo(IN ip char(20),IN port int,IN user
char(30),IN password char(30))
LANGUAGE SQL
COMMENT 'changes master to'
ThisStoredProcedure:BEGIN
SET @sql = 'STOP SLAVE';
PREPARE s FROM @sql; EXECUTE s; DEALLOCATE PREPARE s;
SET @sql = CONCAT('CHANGE MASTER TO MASTER_HOST=',QUOTE(ip));
SET @sql = CONCAT(@sql,',MASTER_PORT=',port);
SET @sql = CONCAT(@sql,',MASTER_USER=',QUOTE(user));
SET @sql = CONCAT(@sql,',MASTER_PASSWORD=',QUOTE(password));
SET @sql = CONCAT(@sql,',MASTER_AUTO_POSITION=1,MASTER_SSL=1');
PREPARE s FROM @sql; EXECUTE s; DEALLOCATE PREPARE s;
END;
//
DELIMITER ;
Best Answer
The error message says
right syntax to use near 'BINARY LOGS TO 'mysql-bin.xxx'
but you mentioned use ofPURGE MASTER LOGS TO ...
?Try using
PURGE MASTER LOGS TO mysql-bin.xxx
instead of using 'PURGE BINARY ....' as the latter was added to MySQL v4.1.1 and if your version is any lower,PURGE BINARY ...
won't work.