2012-02-26 3 views
4

를 사용할 때 1064 우리는 한계 & 양 (limitCount) 매개 변수를 긴 SQL 프로 시저가 있습니다. 그래서 우리는 여러 쿼리를 결합하기 위해 concat 문을 사용하고 있습니다. 이 프로 시저를 호출하면 실행하려고 할 때 err.no 1064가 제공됩니다.MySQL을 저장 프로 시저가 err.no을 제공합니다 : 우리는 CONCAT 문

편집 : 주석을 바탕으로, 나는 전체 코드를 추가하고 있습니다.

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 : DELIMITER이 저장 프로 시저에서 쿼리가 만들어진 방식 때문에

+0

정확히 어떤 오류? 오류가 시작되는 행이나 문자를 지정합니다. –

+0

정확한 오류를 추가했습니다. @Michael – aacanakin

+0

그러나 내 생각 엔 당신이 당신의 쿼리에서 예약어를 사용되면, 어쩌구 blahs없이 전체 쿼리를 게시 도움이 될 것입니다. 어쩌면? – Gary

답변

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

+0

우리가이 쿼리에 대한 concat을 사용하는 경우에도 문제가 여전히 존재합니다. – aacanakin

+0

그리고 concat을 사용하지 않고 제한 절을 사용하지 않으면 어떻게됩니까? 적어도 문제가있는 곳을 알려줘야합니다. – Arjan

관련 문제