当我们使用CONCAT语句时,带有限制参数的MySql存储过程给出了err.no:1064

时间:2012-02-26 14:47:06

标签: mysql stored-procedures

我们有一个很长的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设为//

1 个答案:

答案 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`附近添加了反引号,因为这是问题评论中指出的潜在问题。