【问题标题】:mysql delimiter errormysql分隔符错误
【发布时间】:2010-11-19 00:36:25
【问题描述】:

修改。

DROP FUNCTION IF EXISTS PersonName;
DELIMITER |;

CREATE FUNCTION PersonName( personID SMALLINT )
RETURNS CHAR(20)
BEGIN
  DECLARE pname CHAR(20) DEFAULT '';
  SELECT name INTO pname FROM family WHERE ID=personID;
  RETURN pname;
END;
|
DELIMITER ;

这段代码有什么问题?我收到以下错误。

您的 SQL 查询中似乎有错误。 MySQL服务器错误 下面的输出,如果有的话,可以 还可以帮助您诊断 问题

错误:未知标点字符串@ 102 力量:|; SQL: 删除函数如果 EXISTS PersonName;# MySQL 返回一个 空结果集(即零行)。

分隔符 |;分隔符 |;分隔符 |; 分隔符 |;分隔符 |;分隔符 |; 分隔符 |;

SQL 查询:

分隔符 |;

MySQL 说:文档 #1064 - 您的 SQL 语法有错误;检查手册 对应你的 MySQL 服务器 使用正确语法的版本 'DELIMITER |' 附近在第 1 行

【问题讨论】:

  • 基础,提示:你必须转义像这样\#1064的#(哈希)符号,否则你发布的文本会被格式化为一个标题。

标签: mysql


【解决方案1】:

我最近偶然发现使用 Spring Boot Project 将 MySQL 存储过程与 Liquibase 脚本集成。

  1. 将您的 MySQL 存储过程粘贴到保存在 liquibase 目录下的 GetCustomersWithCreditCardExpiry.sql 文件中。

    DROP PROCEDURE IF EXISTS GetCustomersWithCreditCardExpiry;
    #
    CREATE PROCEDURE GetCustomersWithCreditCardExpiry(IN customer_status VARCHAR(10), IN time_period INT(11))
    BEGIN
    SELECT cs.*
    FROM customer cs
      JOIN credit_card cc
           ON cc.id = cs.credit_card_id
    WHERE cs.status = customer_status
    AND cc.expiry_date < DATE_ADD(now(), INTERVAL time_period HOUR);
    END
    #
    
  2. 在 Liquibase 脚本中添加以下变更集,将 DELIMITER 设为 #

    &lt;changeSet id="1" author="ishaq" runOnChange="true"&gt;

    &lt;sqlFile path="procedures/GetCustomersWithCreditCardExpiry.sql"

    relativeToChangelogFile="true"

    endDelimiter="#"

    splitStatements="true"/&gt;

    &lt;/changeSet&gt;

  3. 在 Spring Boot Java 应用程序中使用存储过程。

     @Query(value = "CALL GetCustomersWithCreditCardExpiry(:customer_status, :time_period);", nativeQuery = true)
     List<CustomerCreditCardRenewal> GetCustomersWithCreditCardExpiry(@Param("customer_status") String customer_status,
                                                                    @Param("time_period") Integer time_period);
    
  4. 实体类映射结果

    @Builder(toBuilder = true)
    @AllArgsConstructor
    @NoArgsConstructor
    @Getter
    @Data
    @Entity
    @NamedStoredProcedureQuery(name = "CustomerCreditCardRenewal.getCustomersWithCreditCardExpiry",
     procedureName = "GetCustomersWithCreditCardExpiry",
     parameters = {
             @StoredProcedureParameter(
                     mode = ParameterMode.IN,
                     name = "customer_status",
                     type = String.class
             ),
             @StoredProcedureParameter(
                     mode = ParameterMode.IN,
                     name = "time_period",
                     type = Integer.class
             )
     })
     public class CustomerCreditCardRenewal {
     //... members
     }
    

当 Spring Boot 应用程序运行时,Liquibase 脚本中的变更集将被执行而不会出现任何错误。 通过使用服务类调用存储库方法,将填充来自存储过程的所需结果。

希望这会对某人有所帮助。

【讨论】:

  • 我遇到了完全相同的问题。感谢您的帮助和努力!
【解决方案2】:

我将把它混在一起,因为它可以帮助其他人解决这个问题。

如果您使用 phpMyAdmin,在 SQL 输入框下方有一个分隔符框,您可以在其中键入用于查询的分隔符。如果需要,您可以将外部分隔符放在这里,然后就不需要分隔符指令了。

例如,如果您将分隔符 $$ 放在框中,您可以使用以下格式进行查询。

CREATE FUNCTION
blah blah...
END 
$$

有些人可能会觉得这更容易。

【讨论】:

    【解决方案3】:

    你必须在mysql脚本的开头和最后添加delimiter $$,你应该以delimiter结尾

    【讨论】:

      【解决方案4】:

      最好的解决方案是,我在收到上述错误后尝试过。代码应该是这样的

      Delimiter //
      Create function or procedure
      Write your function or procedure here...
      End (without semicolon)
      //
      Delimiter ; (semicolon with space)
      

      【讨论】:

        【解决方案5】:

        我的分隔符有问题。我使用的是 Navicat,然后我转到 MySql 工作台,问题就解决了。 Workbench 在代码中插入分隔符...

        【讨论】:

        • 是的,只是遇到了同样的问题。粘贴到控制台窗口,查询工作正常。
        【解决方案6】:

        【讨论】:

          【解决方案7】:

          我会删除END 之后的分号。

              ...
          END
          |
          DELIMITER ;
          

          关于您的评论,声明新分隔符时不能使用当前分隔符。这听起来令人困惑,但考虑一下你是否这样做:

          DELIMITER |;
          

          现在 MySQL 会认为分隔符是“|;” (两个字符,一个竖线和一个分号)。如果您考虑一下,DELIMITER 必须被 MySQL 客户端以特殊方式处理。这是唯一一个不能后跟当前分隔符的语句。

          因此,当将分隔符设置为管道时,请执行以下操作:

          DELIMITER |
          

          将其设置回分号时,请执行以下操作:

          DELIMITER ;
          

          FWIW,我在 MySQL 5.0.75 上的本地测试数据库上运行了以下命令,没有出现错误:

          DROP FUNCTION IF EXISTS PersonName;
          DELIMITER |
          
          CREATE FUNCTION PersonName( personID SMALLINT )
          RETURNS CHAR(20)
          BEGIN
            DECLARE pname CHAR(20) DEFAULT '';
            SELECT name INTO pname FROM family WHERE ID=personID;
            RETURN pname;
          END
          |
          DELIMITER ;
          

          【讨论】:

          • 现在得到 #1064 - 您的 SQL 语法有错误;检查与您的 MySQL 服务器版本相对应的手册,以获取在“DELIMITER |”附近使用的正确语法在第 1 行
          • 我有 5.0.67-community-nt 但它不能在它上面工作.. 不知道为什么.. 我也在在线服务器上尝试过,它是 5.0.81-community,但它给了我用户丢弃表上的访问被拒绝错误..第一行。
          • 感谢您的帮助 :).. 我会尝试一些新功能来查看结果 :)
          【解决方案8】:

          试试这个:

          DROP FUNCTION IF EXISTS PersonName;
          DELIMITER |
          
          CREATE FUNCTION PersonName( personID SMALLINT )
          RETURNS CHAR(20)
          BEGIN
            DECLARE pname CHAR(20) DEFAULT '';
            SELECT name INTO pname FROM family WHERE ID=personID;
            RETURN pname;
          END;
          |
          DELIMITER ; /* <-- add a space between DELIMITER and the semicolon */
          

          【讨论】:

          • 现在我得到 #1064 - 您的 SQL 语法有错误;检查与您的 MySQL 服务器版本相对应的手册,以获取在“DELIMITER |”附近使用的正确语法在第 1 行
          • 好的。让我们试试 mikej 的建议。
          【解决方案9】:

          在将分隔符恢复为分号的最后一行中,DELIMITER; 之间需要一个空格,即

          DELIMITER ;
          

          【讨论】: