我们有一个很长的sql程序,需要限制& amount(limitCount)参数。因此,我们使用concat语句来连接多个查询。当我们尝试运行它时,调用此过程会给出err.no 1064。
编辑:根据评论,我正在添加整个代码。
CREATE PROCEDURE getProfileTasks (IN p_id1 INT, IN p_id2 INT , IN limitStart INT, IN limitCount INT)
BEGIN
SET @SQL = CONCAT('
SELECT P.access_type INTO @privacy FROM Profile P WHERE P.profile_id = ' , p_id2 , ';
IF( ' , p_id1, ' = ' ,p_id2 , ')
THEN
SELECT T.task_id, T.name, D.add_time, D.location, DATE_FORMAT(D.date1, "%d/%m/%y") as `date1`, D.time3, D.state, TIME_FORMAT(D.time1, "%H:%i")as `time1`, D.does_id, IFNULL(L.Like, 0) AS `LikeCount` , IFNULL(C.CommentCount,0) AS `CommentCount` FROM Task T
INNER JOIN Does D on D.task_id = T.task_id
INNER JOIN Profile P on P.profile_id = D.profile_id
LEFT OUTER JOIN (
SELECT D.does_id, COUNT(L.profile_id) as `Like` FROM `Likes` L
INNER JOIN Does D on D.does_id = L.does_id
INNER JOIN Profile P on P.profile_id = D.profile_id
WHERE P.profile_id = ' , p_id2 , '
GROUP BY does_id) L on L.does_id = D.does_id
LEFT OUTER JOIN( SELECT D.does_id, COUNT(C.content) AS `CommentCount` FROM Comment C
INNER JOIN Does D on D.does_id = C.does_id
GROUP BY (D.does_id)) C ON C.does_id = D.does_id
WHERE P.profile_id= ' , p_id2, ' ORDER BY D.add_time DESC LIMIT ' , limitStart , ', ' , limitCount, ';
ELSE
IF (@privacy = 0)
THEN
SELECT T.task_id, T.name, D.add_time, D.location, DATE_FORMAT(D.date1, "%d/%m/%y") as `date1`, D.time3, D.state, TIME_FORMAT(D.time1, "%H:%i")as `time1`, D.does_id, IFNULL(L.Like,0) AS `LikeCount`, IFNULL(C.CommentCount,0) AS `CommentCount` FROM Task T
INNER JOIN Does D on D.task_id = T.task_id
INNER JOIN Profile P on P.profile_id = D.profile_id
LEFT OUTER JOIN (
SELECT D.does_id, COUNT(L.profile_id) as `Like` FROM `Likes` L
INNER JOIN Does D on D.does_id = L.does_id
INNER JOIN Profile P on P.profile_id = D.profile_id
WHERE P.profile_id = ' , p_id2 , '
GROUP BY does_id) L on L.does_id = D.does_id
LEFT OUTER JOIN( SELECT D.does_id, COUNT(C.content) AS `CommentCount` FROM Comment C
INNER JOIN Does D on D.does_id = C.does_id
GROUP BY (D.does_id) )C ON C.does_id = D.does_id
WHERE P.profile_id= ' ,p_id2, ' ORDER BY D.add_time DESC LIMIT ' , limitStart , ', ' , limitCount, ';
ELSE
IF EXISTS ( SELECT * FROM Follows F
INNER JOIN Profile P on F.follower_id = P.profile_id
INNER JOIN Profile P2 on F.following_id = P2.profile_id
WHERE (P.profile_id = ' , p_id1, ' AND P2.profile_id = ' , p_id2 , '))
THEN
SELECT T.task_id, T.name, D.add_time, D.location, DATE_FORMAT(D.date1, "%d/%m/%y") as `date1`, D.time3, D.state, TIME_FORMAT(D.time1, "%H:%i")as `time1`, D.does_id, IFNULL(L.Like,0) AS `LikeCount`, IFNULL(C.CommentCount,0) AS `CommentCount` FROM Task T
INNER JOIN Does D on D.task_id = T.task_id
INNER JOIN Profile P on P.profile_id = D.profile_id
LEFT OUTER JOIN (
SELECT D.does_id, COUNT(L.profile_id) as `Like` FROM `Likes` L
INNER JOIN Does D on D.does_id = L.does_id
INNER JOIN Profile P on P.profile_id = D.profile_id
WHERE P.profile_id = ' , p_id2 , '
GROUP BY does_id) L on L.does_id = D.does_id
LEFT OUTER JOIN( SELECT D.does_id, COUNT(C.content) AS `CommentCount` FROM Comment C
INNER JOIN Does D on D.does_id = C.does_id
GROUP BY (D.does_id) )C ON C.does_id = D.does_id
WHERE P.profile_id= ' , p_id2 , ' ORDER BY D.add_time DESC LIMIT ' , limitStart , ', ' , limitCount, ';
END IF;
END IF;
END IF; '
);
PREPARE query FROM @SQL;
EXECUTE query;
DEALLOCATE PREPARE query;
END
任何人都知道我们为什么会收到此错误?
ERROR : #1064 - 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 'IF( 18 = 18) THEN SELECT T.task_id, T.name, D.add_time, D.location, DATE_' at line 2
P.S:DELIMITER设为//
答案 0 :(得分:1)
由于创建存储过程中的查询的方式实际上并不是服务器友好的(对其他开发人员也不友好),因此我重新格式化了存储过程。然后我还注意到它实际上是在三种情况下执行的相同查询,因此存在大量重复。
CREATE PROCEDURE getProfileTasks (IN p_id1 INT, IN p_id2 INT , IN limitStart INT, IN limitCount INT)
BEGIN
DECLARE privacy INT;
DECLARE is_following INT;
SELECT P.access_type INTO privacy FROM Profile P WHERE P.profile_id = p_id2;
SELECT COUNT(*) INTO is_following
FROM Follows F
INNER JOIN Profile P on F.follower_id = P.profile_id
INNER JOIN Profile P2 on F.following_id = P2.profile_id
WHERE (P.profile_id = p_id1 AND P2.profile_id = p_id2)
LIMIT 1;
IF ( (p_id1 = p_id2) OR (privacy = 0) OR (is_following > 0) )
THEN
-- Using CONCAT and prepared statement because LIMIT won't work otherwise
@SQL = CONCAT('
SELECT
T.task_id
, T.name
, D.add_time
, D.location
, DATE_FORMAT(D.date1, "%d/%m/%y") AS `date1`
, D.time3
, D.state
, TIME_FORMAT(D.time1, "%H:%i") AS `time1`
, D.does_id
, IFNULL(L.`Like`, 0) AS `LikeCount`
, IFNULL(C.CommentCount,0) AS `CommentCount`
FROM Task T
INNER JOIN Does D on D.task_id = T.task_id
INNER JOIN Profile P on P.profile_id = D.profile_id
LEFT OUTER JOIN (
SELECT D.does_id, COUNT(L.profile_id) AS `Like`
FROM `Likes` L
INNER JOIN Does D on D.does_id = L.does_id
INNER JOIN Profile P on P.profile_id = D.profile_id
WHERE P.profile_id = @p_id2
GROUP BY does_id
) L on L.does_id = D.does_id
LEFT OUTER JOIN (
SELECT D.does_id, COUNT(C.content) AS `CommentCount`
FROM Comment C
INNER JOIN Does D on D.does_id = C.does_id
GROUP BY (D.does_id)
) C ON C.does_id = D.does_id
WHERE P.profile_id= @p_id2
ORDER BY D.add_time DESC
LIMIT ', limitStart, ', ' , limitCount, ';');
SET @p_id2 = p_id2;
PREPARE query FROM @SQL;
EXECUTE query USING @p_id2;
DEALLOCATE PREPARE query;
END IF;
END
我还在Like
IFNULL(L.`Like`, 0) AS `LikeCount`
附近添加了反引号,因为这是问题评论中指出的潜在问题。