我是一个MySQL-noob,今天我尝试设置一个长度超过5行的MySQL调用。我一直在学习语法错误,我试着解决几个小时,但我不知道问题是什么。这是代码:
USE myDatabase;
DELIMITER //
CREATE PROCEDURE MYPROC()
BEGIN
SET @ID = 1;
SET @maxID = 3;
CREATE TEMPORARY TABLE resultTable(v DOUBLE, ttc DOUBLE);
WHILE (@ID < @maxID) DO
INSERT partTable1.v, partTable2.ttc
INTO
resultTable
FROM
(SELECT * FROM
(((SELECT time_sec, v FROM speedTable WHERE (trip_id = @ID)) as partTable1)
INNER JOIN
((SELECT time_sec, ttc FROM sightsTable WHERE (trip_id = @ID)) as partTable2) ON
(0.04 > abs(partTable1.time_sec - partTable2.time_sec)))
);
SET @ID := @ID + 1;
END WHILE;
END //
DELIMITER;
CALL MYPROC();
SELECT * FROM resultTable LIMIT 100;
有什么明显的东西需要纠正吗?
Update1:在“CREATE ..” - 语句中添加分号,现在前三个语句都可以。
Update2:又添加了3个分号!
Update3:按照建议使其成为一个函数+单独的函数调用。错误信息已更改!
Update4:我修复了两个答案中提到的问题。还是有点不对劲。请参阅上面的更新代码和下面的错误消息。
更新了错误消息:
ERROR 1064 (42000) at line 4: You have an error in your SQL syntax; check the ma
nual that corresponds to your MySQL server version for the right syntax to use n
ear ' partTable2.ttc
INTO
resultTable
FROM
(SELECT * FROM
(((SELE' at line 11
亲切的问候, 西奥
答案 0 :(得分:0)
其中WHILE
为1的流控制语句只能在存储过程中使用,但您尝试通过控制台将其用作普通查询。
如果您绝对必须采用此路径(使用mysql而不是应用程序语言),请使用所需的代码创建存储过程,然后调用它。
创建过程如下所示:
DELIMITER //
CREATE PROCEDURE MYPROC()
BEGIN
WHILE (@ID < @maxID) DO
SET @partTable1 = (SELECT time_sec, v FROM speedTable WHERE (trip_id = @ID));
SET @partTable2 = (SELECT time_sec, ttc FROM sightsTable WHERE (trip_id = @ID));
INSERT v, ttc INTO resultTable FROM
(@partTable1 INNER JOIN @partTable2 ON
(0.04 > abs(partTable1.time_sec - partTable2.time_sec)));
SET @ID := @ID + 1;
END WHILE;
END//
DELIMITER ;
然后调用它:
CALL MYPROC();
请参阅此SQLFiddle此简化版本。
请注意,您确实有一个语法错误:
@ID = @ID + 1; -- incorrect syntax
SET @ID := @ID + 1; -- correct
答案 1 :(得分:0)
还有一些语法问题和功能问题...
您无法在SQL脚本中使用WHILE
。您只能在存储例程的正文中使用WHILE
。请参阅http://dev.mysql.com/doc/refman/5.6/en/flow-control-statements.html
您无法使用SET
为标量指定多个列。 MySQL不支持关系值变量,只支持标量变量。请参阅http://dev.mysql.com/doc/refman/5.6/en/set-statement.html
您可以使用联接查询结果INSERT
,但必须使用SELECT
引入查询。请参阅http://dev.mysql.com/doc/refman/5.6/en/insert-select.html
您不能将会话变量用作表的名称。您必须使用准备好的声明。请参阅http://dev.mysql.com/doc/refman/5.6/en/prepare.html但是,这会打开一整套不同的蠕虫,并且做错可能是一个安全漏洞(请参阅http://xkcd.com/327)。我不建议你开始使用预处理的语句作为自我描述的MySQL-noob。
这个问题可能比你做的更简单。您不需要临时表,也不需要一次读取一行结果。
以下是我认为符合您的意图的例子:
USE myDatabase
SET @ID = 1;
SET @maxID = 3;
SELECT sp.v, si.ttc
FROM speedTable AS sp
INNER JOIN sightsTable AS si
ON (sp.trip_id = si.trip_id AND 0.04 > ABS(sp.time_sec - si.time_sec))
WHERE sp.trip_id BETWEEN @ID AND @maxID;