这是我第一次处理MySQL中的游标和过程。我已按照MySQL documentation on cursors和roseindia.net中给出的示例进行操作,现在遇到错误:
列数与第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;
目标是在表中使用user-artist(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();
非常感谢任何帮助。 谢谢。
答案 0 :(得分: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);
答案 1 :(得分:0)
在@Jocelyn帮助的INSERT语句上的初始boo-boo之后,我发现我的嵌套循环是错误的。我还必须为嵌套循环添加另一个标签。这是纠正的循环:
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();