【问题标题】:Mysql: ER_PARSE_ERROR: while sending create procedure code from node jsMysql:ER_PARSE_ERROR:从节点 js 发送创建过程代码时
【发布时间】:2019-05-04 09:30:23
【问题描述】:

我正在尝试将创建过程查询从节点 js 发送到 MYSQL。 我正在阅读 Mysql.proc 表以获取存储过程定义。

从 mysql 客户端(如 workbench 或 hedis)提交时,Mysql 代码工作正常

从 NodeJS 提交代码时出现以下错误

{ Error: ER_PARSE_ERROR: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CREATE PROCEDURE `qwe`.`USP_GET_ALL_STOCK_WITH_INDICATORS`( IN `IPV_DATE` DATE )' at line 1
    .
    .
    .
  code: 'ER_PARSE_ERROR',
  errno: 1064,
  sqlMessage:
   'You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near \'CREATE PROCEDURE `qwe`.`USP_GET_ALL_STOCK_WITH_INDICATORS`( IN `IPV_DATE` DATE )\' at line 1',
  sqlState: '42000',
  index: 0,
  sql:
   'USE qwe;    CREATE PROCEDURE `qwe`.`USP_GET_ALL_STOCK_WITH_INDICATORS`( IN `IPV_DATE` DATE )BEGIN IF NOT EXISTS(SELECT 1 FROM StockCandle where `DATE`=IPV_DATE) THEN SET @D:=(SELECT MAX(`DATE`) FROM StockCandle); ELSE SET @D:=IPV_DATE; END IF; -- select @D; SELECT  SM.Symbol, SM.MA13, SM.MA8, SM.MA5, CASE WHEN SM.MA5>SM.MA8 AND SM.MA8>MA13 THEN \'>>>\' WHEN SM.MA5<SM.MA8 AND SM.MA8<MA13 THEN \'<<<\' ELSE NULL
END ALLIGATOR ,SM.RSI, SM.BHAVTIME, SM.CANDLEINDICATOR FROM StockMaster SM  where SM.DATE=@D; END // ' }

尝试下面的代码来解析节点中的 sql

formattdSQL = formattdSQL.replace(/(?:\\[rtn]|[\r\t]+)+/g, ' ');

查询获取过程

SELECT `name`, CONVERT(param_list USING utf8), CONVERT(body USING utf8)
INTO @spname, @spparams, @spbody
FROM mysql.proc WHERE `name` = 'USP_GET_ALL_STOCK_WITH_INDICATORS' AND db = v_oldDB;
SET @sql = CONCAT(@sql, '\r\n', 'DELIMITER //','\r\n','CREATE PROCEDURE `', v_newDB, '`.`', @spname, '`(', @spparams,')',@spbody, ' //', '\r\n','');

我希望创建过程查询应该从节点成功执行

【问题讨论】:

    标签: mysql node.js stored-procedures escaping


    【解决方案1】:

    DELIMITER 指令不是 MySQL Server SQL 的一部分。这仅与交互式 client 实用程序一起使用,这些实用程序将输入流或屏幕文本框的内容解析为单独的语句——如工作台或(可能)“hedis”(无论是什么) .

    当您使用编程库发送查询时,您不会使用它。

    只需将过程声明作为单个查询发送。在此之前将USE 语句作为单独的查询发送。

    第一个查询:

    USE qwe
    

    (第一个查询中的尾随分号实际上不是服务器所期望的,但如果您发送它是允许的。)

    第二次查询:

    CREATE PROCEDURE ...
    ...
    END
    

    之前不应该有DELIMITER //,之后也不应该有//。这些都是客户端构造,对服务器没有意义。

    无需使用您的formattdSQL.replace(...) 语句来删除换行符。这只会使您的代码不可读,并且不需要。

    【讨论】:

    • 谢谢@Michael 删除 USE DB 有效,我需要一次性发送 100 个 sprc 定义,我应该在每个 proc 定义的末尾使用什么分隔符?现在我只能发送单个 proc。
    • 可能可以在连接选项中设置multipleStatements: true,然后使用;,但该选项非常糟糕,因为它会产生某些SQL注入漏洞可能的,默认情况下是不可能的。如果您打开 MySQL 服务器常规查询日志,您会发现工作台,不会一次发送多个查询。每个 proc 定义将作为单独的查询发送。
    猜你喜欢
    • 2018-07-28
    • 1970-01-01
    • 1970-01-01
    • 2017-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多