2013-12-14 1 views
1

How can I loop through all rows of a table? (MySQL) 다음 코드를 게시했습니다 :구문 오류 동안이 질문에 대한 허용 대답에서

INSERT INTO table_B(ID, VAL) VALUES(ID, VAL) FROM table_A LIMIT i,1; 

내가 저를 허용하는 첫 번째 변수로 table_A에서 선택합니다

SELECT VAL FROM table_A INTO variableVal LIMIT i, 1; 
INSERT INTO table_B(ID, VAL) VALUES(ID, variableVal); 

를하지만 나에게 구문 오류가 있습니다 :이처럼 재사용

#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 'LIMIT i, 1;

다음은 전체 코드입니다

DROP PROCEDURE IF EXISTS ROWPERROW; 
DELIMITER ;; 
CREATE PROCEDURE ROWPERROW() 
BEGIN 
    DECLARE i INT DEFAULT 0; 
    DECLARE factionCount INT DEFAULT 0; 
    DECLARE factionName varchar(100); 
    SELECT COUNT(*) FROM faction INTO factionCount; 

    SET i = 0; 
    WHILE i < factionCount DO 
    SELECT name FROM faction INTO factionName LIMIT i, 1; 
    //SELECT name FROM faction LIMIT i, 1 INTO factionName; (doesn't work either) 

    INSERT INTO groups_group(name) values (factionName); 

    //going to do something else with factionName 
    SET i = i + 1; 
    END WHILE; 
End; 
;; 

call ROWPERROW(); 
+0

당신이'factionName'에 대해 수행 할 수 있습니까? 루프 및 커서없이 할 수 있습니다. – peterm

답변

2

즉시 오류는 사용자의 SELECT INTO 구문이 잘못되어 발생합니다. INTO 절은 FROM 앞에 있어야합니다. 여기

DELIMITER $$ 
CREATE PROCEDURE ROWPERROW() 
BEGIN 
    DECLARE i INT DEFAULT 0; 
    DECLARE factionCount INT DEFAULT 0; 
    DECLARE factionName varchar(100); 
    SELECT COUNT(*) INTO factionCount FROM faction ; 

    SET i = 0; 
    WHILE i < factionCount DO 
    SELECT name INTO factionName FROM faction LIMIT i, 1; 
    INSERT INTO groups_group(name) VALUES (factionName); 

    -- going to do something else with factionName 
    SET i = i + 1; 
    END WHILE; 
END$$ 
DELIMITER ; 

이 기술적으로 가능하고 난 강력하게 데이터를 처리에서 당신을을 억제 작업에도 불구하고 지금 SQLFiddle 데모

처럼 프로 시저의

구문이 올바른 버전이 보일 수 있습니다 그 방법.

  1. 전혀 LOOP를 사용하지 마십시오. 프로 시저가 작동하는 동안 다른 세션에서 몇 줄을 삭제하면 코드가 손상됩니다.

  2. 행 당 행 처리를 원하면 적어도 커서를 사용하십시오.

  3. 데이터 세트 접근 방식으로 처리 할 수있는 경우 (대부분의 경우 커서에서 멀리 떨어져있을 수 있음).


커서가있는 버전은 다음과 같을 수 있습니다 여기에

DELIMITER$$ 
CREATE PROCEDURE ROWPERROW2() 
BEGIN 
    DECLARE done INT DEFAULT 0; 
    DECLARE factionName varchar(100); 
    DECLARE cursor1 CURSOR FOR SELECT name FROM faction; 
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; 

    OPEN cursor1; 

    read_loop: LOOP 
    FETCH cursor1 INTO factionName; 
    IF done THEN 
     LEAVE read_loop; 
    END IF; 
    INSERT INTO groups_group(name) VALUES (factionName); 

    -- going to do something else with factionName 
    END LOOP; 

    CLOSE cursor1; 
END$$ 
DELIMITER ; 

입니다 SQLFiddle 데모

+0

첫 번째 해결책이 작동하지 않습니다. 누군가 다른 사람이 말한 것처럼 MySQL 버전 때문일 수 있다고 생각하십니까? 나는 커서를 살펴볼 것입니다. 성능이 문제가되지는 않습니다. 단지 일회성 일뿐입니다. 서버가 정지 된 동안 Minecraft 플러그인의 버전을 업그레이드하는 사람들을위한 것입니다. – Jonathan

+0

현재 사용중인 MySQL 버전은 무엇입니까? 그리고 나는 당신이 어쨌든'LOOP '을 사용하고 싶지 않다고 말했다. 성능에 관한 것이 아니라 상식에 관한 것입니다. 세트 기반 접근법에 대한 도움이 필요하다면 필자가 제공 한 커서로 실제 예제를 시도하거나 실제 목표가 무엇인지 설명하십시오. – peterm

+0

결국 대답이 도움이 되었습니까? – peterm

0

변수 앞에 @를 넣어야합니다.

+0

@는 나에게 구문 오류를 알려주지 만, 나는 그것들이 그것 없이는 작동 할 수 있기 때문에 거기에 넣어야한다고 생각하지 않는다. @가 부족하여 현재 구문 오류가 발생하고 있다고 생각하지 않습니까? – Jonathan

1

변수를 LIMIT과 함께 사용할 수 없습니다. 행을 반복하려면 CURSOR를 대신 사용하십시오.

일반적인 SQL 문을 사용하여 SQL의 집합 기반 접근법을 사용하는지 확인하십시오. 일반적으로 일반 SQL 명령을 사용하면 성능이 훨씬 좋아 지므로 루프/커서를 사용하는 것이 최후의 수단이되어야합니다.

+0

성능에 문제가 없으므로 커서를 살펴 보겠습니다. – Jonathan

+0

당신은 ** 변수를 사용할 수 있습니다 (LIMIT' 절에 블록 수준과 사용자 (세션) 수준 모두 저장 가능). – peterm

+0

이것은 MySQL 버전에 따라 다릅니다. Limit는 MySQL 5.5.6에서만 변수를받습니다. Jonny가 이전 버전을 실행 중이라는 오류 메시지를 기반으로합니다. – slaakso