首页 文章

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

提问于
浏览
1

我想从以下 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行的'delimiter $$'附近使用正确的语法

我该如何解决?

5 回答

  • 0

    当您通过API执行语句时,绝对不要尝试更改分隔符 . DELIMITERmysql client built-in command,MySQL服务器端解析器无法识别它 .

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

    同样,不要使用 $$ 结束create trigger语句 . 您不需要任何语句终止符,但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保留字 . The set of reserved words is documented.

  • 6

    试试看:

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

相关问题