2012-02-26 42 views
4

我們有一個很長的sql過程,它需要限制& amount(limitCount)參數。所以,我們使用concat語句來加入多個查詢。當我們嘗試運行它時,調用這個過程會導致err.no 1064。當我們使用CONCAT語句時,帶有限制參數的MySql存儲過程給出了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 

PS:分隔符設置爲//

+0

確切的錯誤是什麼?它可能會指定錯誤開始的行或字符。 – 2012-02-26 14:49:43

+0

我已經添加了確切的錯誤。 @邁克爾 – aacanakin 2012-02-26 14:58:05

+0

將有助於發佈完整的查詢沒有blah-blahs,但我的猜測是你在查詢中使用保留字。也許喜歡? – Gary 2012-02-26 15:21:48

回答

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 

而且我在IFNULL(L.`Like`, 0) AS `LikeCount`也加入反引號周圍Like,因爲這是在問題的評論中指出的潛在問題。

+0

mysql不接受限制值作爲參數。這就是爲什麼我們在創建過程中使用concat操作。但看起來更容易閱讀和理解。讓我嘗試轉換此查詢以concat格式並再次嘗試 – aacanakin 2012-02-26 22:17:52

+0

即使我們對此查詢使用concat,問題依然存在 – aacanakin 2012-02-26 22:25:55

+0

如果您不使用concat並且也不使用limit子句,會發生什麼情況?它至少應該讓你指出問題所在。 – Arjan 2012-02-26 22:38:51

相關問題