サードパーティベンダーからデータをインポートしています。それらのテーブルを既存のデータベースにインポートしました。ここで、person
レコードのそれぞれを反復処理し、少し変更して、端のいくつかのテーブルに挿入するだけです。私のカーソルは1回だけ反復しているようですが、これがコードです。
DELIMITER @@
DROP PROCEDURE IF EXISTS import_members@@
CREATE PROCEDURE import_members ()
BEGIN
-- Declare loop constructs --
DECLARE done INT DEFAULT FALSE;
-- Declare Person variables --
DECLARE person_id INT;
DECLARE era_username VARCHAR(100);
DECLARE last_name VARCHAR(50);
DECLARE first_name VARCHAR(50);
DECLARE email VARCHAR(100);
DECLARE email_primary VARCHAR(50);
DECLARE degree_id_1 INT;
DECLARE degree_id_2 INT;
DECLARE member_status INT;
DECLARE user_id INT;
DECLARE user_email VARCHAR(100);
-- Declare Cursor --
DECLARE member_cursor CURSOR FOR
SELECT person_id, era_username, last_name, first_name, TRIM(email), TRIM(email_primary), degree_id_1, degree_id_2, member_status
FROM z_data_person
WHERE member_status IS NOT NULL;
-- Declare Continue Handler --
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
OPEN member_cursor;
read_loop: LOOP
-- Fetch data from cursor --
FETCH member_cursor
INTO person_id, era_username, last_name, first_name, email, email_primary, degree_id_1, degree_id_2, member_status;
-- Exit loop if finished --
IF done THEN
LEAVE read_loop;
END IF;
-- Create User --
SET user_id = SELECT (MAX(uid) + 1) FROM users;
IF email_primary IS NOT NULL AND email_primary NOT LIKE '%null%' THEN
SET user_email = email_primary;
ELSE
SET user_email = email;
END IF;
INSERT INTO `users` (`uid`, `name`, `pass`, `mail`, `created`)
VALUES (user_id, era_username, SHA1(Rand()), user_email, UNIX_TIMESTAMP());
-- Create Member --
INSERT INTO `members` (`uid`, `first_name`, `last_name`, `phone`, `member_category_id`, `subscription_weekly_email`, `subscription_monthly_newsletter`)
VALUES (user_id, first_name, last_name, phone_num, member_status, weekly_com, monthly_com);
-- Add Degrees --
IF degree_id_1 IS NOT NULL THEN
INSERT INTO member_degrees_held
VALUES (user_id, degree_id_1);
END IF;
IF degree_id_2 IS NOT NULL THEN
INSERT INTO member_degrees_held
VALUES (user_id, degree_id_2);
END IF;
-- Add Areas of Expertise --
INSERT INTO `member_expertises_held` (`uid`, `specialty_id`)
SELECT (SELECT MAX(uid) FROM users), z.specialty_id
FROM z_map_person_specialty AS z
WHERE z.person_id = person_id;
END LOOP read_loop;
CLOSE member_cursor;
END; @@
DELIMITER ;
CALL import_members();
カーソルの設定に使用されたSELECT
ステートメントが結果を返さないかのようです。私はそれを個別にテストしましたが、結果は正しく返されます。最初のFETCH
のすぐ下にSELECT person_id
を入れてみましたが、戻り値はNULL
です。したがって、このクエリは結果を返す必要がありますが、カーソルの結果セットには含まれません。何か不足していますか?
すべてのローカル変数にmy_などのタグを付けてみてください
DELIMITER @@
DROP PROCEDURE IF EXISTS import_members@@
CREATE PROCEDURE import_members ()
BEGIN
-- Declare loop constructs --
DECLARE done INT DEFAULT FALSE;
-- Declare Person variables --
DECLARE my_person_id INT;
DECLARE my_era_username VARCHAR(100);
DECLARE my_last_name VARCHAR(50);
DECLARE my_first_name VARCHAR(50);
DECLARE my_email VARCHAR(100);
DECLARE my_email_primary VARCHAR(50);
DECLARE my_degree_id_1 INT;
DECLARE my_degree_id_2 INT;
DECLARE my_member_status INT;
DECLARE my_user_id INT;
DECLARE my_user_email VARCHAR(100);
-- Declare Cursor --
DECLARE member_cursor CURSOR FOR
SELECT person_id, era_username, last_name, first_name,
TRIM(email), TRIM(email_primary), degree_id_1, degree_id_2,
member_status FROM z_data_person
WHERE member_status IS NOT NULL;
-- Declare Continue Handler --
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
OPEN member_cursor;
read_loop: LOOP
-- Fetch data from cursor --
FETCH member_cursor
INTO my_person_id, my_era_username, my_last_name, my_first_name,
my_email, my_email_primary, my_degree_id_1, my_degree_id_2,
my_member_status;
-- Exit loop if finished --
IF done THEN
LEAVE read_loop;
END IF;
-- Create User --
SET my_user_id = SELECT (MAX(uid) + 1) FROM users;
IF my_email_primary IS NOT NULL AND my_email_primary NOT LIKE '%null%' THEN
SET my_user_email = my_email_primary;
ELSE
SET my_user_email = my_email;
END IF;
INSERT INTO `users` (`uid`, `name`, `pass`, `mail`, `created`)
VALUES (my_user_id, my_era_username, SHA1(Rand()), my_user_email, UNIX_TIMESTAMP());
-- Create Member --
INSERT INTO `members` (`uid`, `first_name`, `last_name`, `phone`,
`member_category_id`, `subscription_weekly_email`,
`subscription_monthly_newsletter`)
VALUES (my_user_id, my_first_name, my_last_name, my_phone_num,
my_member_status, my_weekly_com, my_monthly_com);
-- Add Degrees --
IF degree_id_1 IS NOT NULL THEN
INSERT INTO member_degrees_held
VALUES (my_user_id, my_degree_id_1);
END IF;
IF degree_id_2 IS NOT NULL THEN
INSERT INTO member_degrees_held
VALUES (my_user_id, my_degree_id_2);
END IF;
-- Add Areas of Expertise --
INSERT INTO `member_expertises_held` (`uid`, `specialty_id`)
SELECT (SELECT MAX(uid) FROM users), z.specialty_id
FROM z_map_person_specialty AS z
WHERE z.person_id = my_person_id;
END LOOP read_loop;
CLOSE member_cursor;
END; @@
DELIMITER ;
CALL import_members();
本 MySQLストアドプロシージャプログラミング では、すべてのカーソルの例は、ローカル変数に対応するテーブル列からの一意の名前を与えます(本がある場合は、108ページの例5-15を参照してください)。
サイドノート:weekly_comとmonthly_comはどこから来ていますか???
私も同じような問題に直面しました。
ローカル変数名とテーブル列名は同じであってはなりません。
ローカル変数にいくつかの文字を追加して試してください。その後、それは間違いなく動作します。
ローカル変数のすべての列にV_を追加しましたが、うまくいきました。