从PHP代码创建触发器时出现语法错误


Syntax error when creating trigger from PHP code

我想从以下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服务器版本,以获得正确的语法在第1行使用"分隔符$$"附近

我该怎么修?

通过API执行语句时,绝对不要尝试更改分隔符。DELIMITER是mysql客户端内置的命令,mysql服务器端解析器无法识别。

你根本不需要它。DELIMITER的目的是消除可能出现在触发器或存储例程主体内的分号的歧义。由于API用于一次执行一条语句,因此不存在歧义。无论如何,SQL解析器只是将整个字符串视为一条语句。

同样,不要以$$结束create触发器语句。您不需要任何语句终止符,但SQL解析器接受;作为可选的语句终止符

下一个问题是,当你在触发器中使用列名时,你必须用NEW.OLD.作为前缀——在插入触发器中,你只能使用NEW.。如果你不给列加前缀,MySQL假设你想设置一个像tmpdirslow_query_log这样的系统变量。

如果您仍然得到1193错误,我建议您不要将name列的两个引用都更改为NEW.name

我使用PHP 5.4.24和MySQL 5.6.20测试了以下内容,结果成功了:

$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);

您不需要对name的列名进行定界,因为它不是MySQL的保留字。保留字集已记录在案。

尝试一下:

  $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);

由于您使用代码创建触发器,因此可能不需要设置/重置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);

也许这有助于:

$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);

由于您使用代码创建触发器,因此可能不需要设置/重置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);