过程适用于mysql工作台,但不适用于C ++连接器

时间:2014-04-11 15:37:49

标签: c++ mysql mysql-connector

我有一个在MySQL Workbench中执行的过程并且没有错误:

DELIMITER //
CREATE PROCEDURE test()
BEGIN
    DECLARE maxwf_fir INT DEFAULT 0;
    SET maxwf_fir = (SELECT MAX(wf_fir) FROM establishment);
    WHILE maxwf_fir > 0 DO
        UPDATE individual AS i LEFT JOIN establishment AS e USING (establishment_id) SET 
        wf_fir = wf_fir-1,
        e.wf_est = e.wf_est-1,
        i.labor = 2,
        i.labor_periods = 0,
        i.establishment_id = 0
        WHERE (e.wf_hir <= e.wf_fir)
        AND (wf_fir > 0);

        UPDATE individual AS i LEFT JOIN establishment AS e USING (establishment_id) SET 
        e.counter1 = e.counter1+1
        WHERE (e.wf_hir <= e.wf_fir)
        AND (wf_fir > 0);

        UPDATE individual AS i LEFT JOIN establishment AS e USING (establishment_id) SET 
        e.counter1 = 0,
        e.counter2 = e.counter2+1
        WHERE (e.wf_hir <= e.wf_fir)
        AND (wf_fir > 0)
        AND (e.counter1 = e.wf_est);

        SET maxwf_fir = maxwf_fir-1;
    END WHILE;
END//

DELIMITER ;
CALL test;

DROP PROCEDURE test;

然而,当我使用C ++连接器的一些代码时,我被告知存在语法错误,但代码完全相同(我从工作台复制并粘贴到Geany中):

std::stringstream query4;
//query4 << "drop procedure if exists loop;\n";
query4 << "DELIMITER //\n";
query4 << "CREATE PROCEDURE loop()\n";
query4 << "BEGIN\n";
query4 << "\tDECLARE maxwf_fir INT DEFAULT 0;\n";
query4 << "\tSET maxwf_fir = (SELECT MAX(wf_fir) FROM establishment);\n";
query4 << "\tWHILE maxwf_fir > 0 DO\n";
query4 << "\t\tUPDATE individual AS i LEFT JOIN establishment AS e USING (establishment_id) SET\n";
query4 << "\t\te.wf_fir = e.wf_fir-1,\n";
query4 << "\t\te.wf_est = e.wf_est-1,\n";
query4 << "\t\ti.labor = 2,\n";
query4 << "\t\ti.labor_periods = 0,\n";
query4 << "\t\ti.establishment_id = 0\n";
query4 << "\t\tWHERE (e.wf_hir <= e.wf_fir)\n";
query4 << "\t\tAND (e.wf_fir > 0)\n";
query4 << "\t\tAND e.temp < POW("<< Coeffs::gamma67 << ", e.counter2)*" << random << ";\n";

query4 << "\t\tUPDATE individual AS i LEFT JOIN establishment AS e USING (establishment_id) SET\n";
query4 << "\t\te.counter1 = e.counter1+1\n";
query4 << "\t\tWHERE (e.wf_hir <= e.wf_fir)\n";
query4 << "\t\tAND NOT (e.temp < POW("<< Coeffs::gamma67 << ", e.counter2)*" << random << ")\n";
query4 << "\t\tAND (wf_fir > 0);\n";

query4 << "\t\tUPDATE individual AS i LEFT JOIN establishment AS e USING (establishment_id) SET\n";
query4 << "\t\te.counter1 = 0\n";
query4 << "\t\te.counter2 = e.counter2+1\n";
query4 << "\t\tWHERE (e.wf_hir <= e.wf_fir)\n";
query4 << "\t\tAND NOT (e.temp < POW("<< Coeffs::gamma67 << ", e.counter2)*" << random << ")\n";
query4 << "\t\tAND e.counter1 = e.wf_est\n";
query4 << "\t\tAND (wf_fir > 0);\n";

query4 << "\t\tSET maxwf_fir = maxwf_fir-1;\n";
query4 << "\tEND WHILE;\n";
query4 << "END//\n";
query4 << "DELIMITER ;\n";
query4 << "CALL loop;\n";
query4 << "DROP PROCEDURE loop;\n";
stmt->execute(query4.str());

这给了我错误:

terminate called after throwing an instance of 'sql::SQLException'
  what():  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 'DELIMITER //
CREATE PROCEDURE loop()
BEGIN
    DECLARE maxwf_fir INT DEFAULT 0;
    SE' at line 1
Aborted (core dumped)

任何人都可以在导致此错误的C ++代码中看到我做错了吗? 提前谢谢!

3 个答案:

答案 0 :(得分:1)

从SQL引擎以外的界面创建存储过程时,delimiter是可选的。示例@ SQL FIddle

更改1

删除声明

query4 << "DELIMITER //\n";

更改2

loopReserved Word。如果您仍希望对程序使用相同的名称,请将其作为

后面的刻度括起来
`loop()`

更改3

query4 << "END//\n";

query4 << "END;\n"; // semi-colon is optional, if it is last statement in the sp

更改4

删除声明

query4 << "DELIMITER ;\n";

更改5

query4 << "CALL loop;\n";
query4 << "DROP PROCEDURE loop;\n";

query4 << "CALL `loop`();\n";
query4 << "DROP PROCEDURE `loop`;\n";

答案 1 :(得分:1)

首先,做Ravinder的答案中提到的内容。调用execute()时不需要“DELIMITER”语句,并且API足够聪明,可以理解存储过程体内的分号不是命令的结尾。事实上,c ++ executeUpdate()抱怨使用“DELIMITER”,但是我想,执行()只是默默地失败。

其次,在创建连接时启用CLIENT_MULTI_STATEMENTS选项,因为您尝试一次执行多个语句。或者逐个执行它们。

要为C ++启用多个语句,您可以编写如下内容:

sql::Driver* driver = get_driver_instance();
sql::Connection *con = driver->connect("tcp://host:3306", "user", "pass");
bool myTrue = true;
con->setClientOption("CLIENT_MULTI_STATEMENTS", &myTrue);

或使用不同版本的driver-&gt; connect(),如下所示:

sql::ConnectOptionsMap connection_properties;
connection_properties["hostName"] = "host";
connection_properties["port"] = (3306);
connection_properties["userName"] = "user";
connection_properties["password"] = "pass";
connection_properties["CLIENT_MULTI_STATEMENTS"] = (true);
sql::Connection *con = driver->connect(connection_properties));

答案 2 :(得分:0)

可能你的问题是程序的名称“循环”是一个保留字,它是否在工作台中使用“循环”而不是“测试”?