2012-09-09 77 views
0

這是我第一次處理MySQL中的遊標和過程。我已按照MySQL documentation on cursorsroseindia.net給出的例子,現在遇到一個錯誤:嵌套遊標循環:列計數與第1行的值計數不匹配

Column count doesn't match value count at row 1

以下是參與(該表是不歸一3NF但我收到他們爲這樣的表,是的,我不認識我會需要使用artists.id代替artists.name):

CREATE TABLE `user_artists_rankings` (
    `user_id` varchar(50) NOT NULL DEFAULT '' COMMENT 'kpop_users.user_id', 
    `artist_name` varchar(100) NOT NULL, 
    `calculated_score` int(11) DEFAULT NULL, 
    `last_calculated_score_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP, 
    PRIMARY KEY (`user_id`,`artist_name`) 
) ENGINE=MyISAM DEFAULT CHARSET=utf8; 
CREATE TABLE `kpop_users` (
    `user_id` char(50) NOT NULL, 
    `username` char(150) DEFAULT '', 
    `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, 
    PRIMARY KEY (`user_id`) USING BTREE, 
    KEY `name_idx` (`username`), 
    KEY `twitter_id_idx` (`twitter_user_id`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; 
CREATE TABLE `artists` (
    `name` varchar(100) NOT NULL, 
    `type` varchar(45) DEFAULT NULL, 
    `official_twitter_screenname` varchar(45) DEFAULT NULL, 
    `thumbnail_url` varchar(500) DEFAULT NULL, 
    `id` int(10) unsigned NOT NULL AUTO_INCREMENT, 
    PRIMARY KEY (`id`), 
    KEY `Index_2` (`official_twitter_screenname`) 
) ENGINE=InnoDB AUTO_INCREMENT=164 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; 

的目標是讓用戶藝術家(N)表中的行,user_artists_rankings,即:

user1 | artist1 
user1 | artist2 
user1 | artist3 
user2 | artist1 
user2 | artist2 
user2 | artist3 

這裏是我創造的過程:

delimiter ; 
drop procedure if exists testrun; 
delimiter // 
create procedure testrun() 
begin 
    declare d int default 0; 
    declare user_id varchar(50); 
    declare artist_name varchar(100); 
    declare cur_users cursor for select user_id from kpop_users; 
    declare cur_artists cursor for select name from artists; 
    declare continue handler for sqlstate '02000' set d=1; 
    declare continue handler for sqlstate '23000' set d=1; 
    open cur_users; 
    open cur_artists; 
    lbl1: loop 
     if d=1 then 
      leave lbl1; 
     end if; 
     if not d=1 then 
      fetch cur_users into user_id; 
      lbl2: loop 
       if d=1 then 
        leave lbl2; 
       end if; 
       if not d=1 then 
        fetch cur_artists into artist_name; 
        insert into user_artists_rankings values (user_id, artist_name); 
       end if; 
      end loop lbl2; 
     end if; 
    end loop lbl1; 
    close cur_users; 
    close cur_artists; 
end 
// 
delimiter ; 
call testrun(); 

任何幫助將不勝感激。 謝謝。

回答

1

這行代碼是錯誤的:

insert into user_artists_rankings values (user_id, artist_name); 

由於該表有4個字段,只使用其中的兩個用於INSERT,你需要指定要使用的。它應該是:

insert into user_artists_rankings(`user_id`, `artist_name`) VALUES(user_id, artist_name); 
0

的INSERT語句,該語句@Jocelyn幫助了,最初的噓,噓之後,我發現我的嵌套循環是錯誤的。我必須爲嵌套循環添加另一個標籤。這是修正的循環:

delimiter ; 
DROP procedure IF EXISTS firstrunUser_Artists_Rankings; 
delimiter // 
CREATE PROCEDURE firstrunUser_Artists_Rankings() 
block1: BEGIN 
    DECLARE d INT DEFAULT 0; 
    DECLARE new_user_id VARCHAR(50); 
    DECLARE new_artist_id INT(10); 
    DECLARE cur_users CURSOR FOR SELECT `user_id` FROM kpop_users; 
    DECLARE cur_artists CURSOR FOR SELECT `id` FROM artists; 
    DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET d=1; 
    DECLARE CONTINUE HANDLER FOR SQLSTATE '23000' SET d=1; 
    OPEN cur_users; 
    lbl1: LOOP 
     IF d=1 THEN 
     SHOW ERRORS; 
      LEAVE lbl1; 
     END IF; 
     IF NOT d=1 THEN 
      FETCH cur_users INTO new_user_id; 
      block2: BEGIN 
      DECLARE e INT DEFAULT 0; 
      DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET e=1; 
     DECLARE CONTINUE HANDLER FOR SQLSTATE '23000' SET e=1; 
      OPEN cur_artists; 
      lbl2: LOOP 
       IF e=1 THEN 
        LEAVE lbl2; 
       END IF; 
       IF NOT e=1 THEN 
        FETCH cur_artists INTO new_artist_id; 
        INSERT INTO user_artists_rankings(`user_id`, `artist_id`) VALUES (new_user_id, new_artist_id); 
        INSERT INTO user_artists_rankings_raw(`user_id`, `artist_id`) VALUES (new_user_id, new_artist_id); 
       END IF; 
      END LOOP lbl2; 
      CLOSE cur_artists; 
      END block2; 
     END IF; 
    END LOOP lbl1; 
    CLOSE cur_users; 
END block1; 
// 
delimiter ; 
CALL firstrunUser_Artists_Rankings(); 
相關問題