我想从以下PHP
代码创建触发器。
$sql = 'delimiter $$';
$pdo->exec($sql);
$sql = 'create trigger avoid_empty_employee_insert before insert on `employee`
for each row begin
if name = "" then set name = null; end if;
end$$';
$pdo->exec($sql);
$sql = 'delimiter ;';
$pdo->exec($sql);
当我运行MySQL
中的代码时,它可以工作并创建触发器。
PHP显示以下错误。
SQLSTATE [42000]:语法错误或访问 违规:1064您的SQL语法有错误;检查手册 对应于您的MySQL服务器版本,以获得正确的语法 使用near' delimiter $$'在第1行
我该如何解决?
答案 0 :(得分:7)
当您通过API执行语句时,绝对不要尝试更改分隔符。 DELIMITER
是mysql client built-in command,MySQL服务器端解析器无法识别它。
无论如何你根本不需要它。 DELIMITER
的目的是消除可能出现在触发器或存储例程体内的分号的模糊性。由于API用于一次执行一个语句,因此没有歧义。 SQL解析器只是将整个字符串视为一个语句。
同样,不要使用$$
结束创建触发器语句。您不需要任何语句终止符,但SQL解析器接受;
作为可选语句终止符,因为很多人将它放在那里,即使他们没有。
下一个问题是,当您在触发器中使用列名时,必须在{1}}或NEW.
前加上它们 - 在插入触发器中,您只能使用{{1如果你没有为列添加前缀,MySQL会假设您要设置一个类似OLD.
或NEW.
的系统变量。
如果您仍然收到1193错误,我建议您不要将对tmpdir
列的两个引用更改为slow_query_log
。
我使用PHP 5.4.24和MySQL 5.6.20对以下内容进行了测试,结果如下:
name
您不需要分隔NEW.name
的列名,因为它不是MySQL保留字。 The set of reserved words is documented.
答案 1 :(得分:0)
试试:
$sql = 'create trigger avoid_empty_employee_insert before insert on `employee`
for each row begin
if name = "" then set name = null; end if; END;';
$pdo->exec($sql);
答案 2 :(得分:0)
由于您是使用代码创建触发器,因此可能不需要设置/重置DELIMITER
。更改DELIMITER对于CLI非常重要。
只需忽略php代码中那些更改它们的行。
您的代码仅限:
$sql = 'create trigger `avoid_empty_employee_insert` before insert
on `employee`
for each row
begin
if `name` = "" then set `name` = null; end if;
end';
$pdo->exec($sql);
答案 3 :(得分:0)
由于您是使用代码创建触发器,因此可能不需要设置/重置DELIMITER
。
只需忽略php代码中那些更改它们的行。
您的代码仅限:
$sql = 'create trigger avoid_empty_employee_insert before insert on `employee`
for each row begin
if NEW.`name` = "" then set NEW.`name` = null; end if;
end$$';
$pdo->exec($sql);
答案 4 :(得分:0)
Mayby这有助于:
$sql = "delimiter //\n";
$pdo->exec($sql);
$sql = "create trigger avoid_empty_employee_insert before insert on employee\n
for each row\n
begin\n
if new.name = '' then\n
set new.name = null;\n
end if;\n
end//\n";
$pdo->exec($sql);
$sql = 'delimiter ;';
$pdo->exec($sql);