이 저장 프로 시저를 사용하는 것이 좋습니다. 누군가 내 실수를 설명 할 수 있기를 기대하면서 전체 덤프를 게시합니다.동적보기가있는 저장 프로 시저가 필드 수를 새로 고치지 않습니다.
drop table if exists questions;
create table questions (
id int not null auto_increment primary key,
description varchar(200)
) engine = myisam;
insert into questions (description)
values
('Question 1'),
('Question 2'),
('Question 3');
drop table if exists answers;
create table answers (
id int not null auto_increment primary key,
question_id int,
description varchar(10)
) engine = myisam;
insert into answers (question_id,description)
values
(1,'no'),
(1,'no'),
(1,'yes'),
(1,'no'),
(1,'yes'),
(2,'no'),
(2,'yes'),
(2,'yes'),
(2,'yes'),
(2,'no'),
(2,'no'),
(2,'no'),
(2,'yes'),
(2,'no'),
(3,'no'),
(3,'no'),
(3,'no'),
(3,'yes');
이 내 저장 프로 시저입니다 :
delimiter //
drop procedure if exists dynamic_view //
create procedure dynamic_view()
begin
declare cnt int default 0;
declare finito int default 0;
declare qid int;
declare qdescription varchar(100);
declare qanswer varchar(100);
declare i int default 1;
declare j int;
declare str varchar(20000) default '';
declare str2 varchar(20000);
declare str3 varchar(20000);
declare curs1 cursor for select id,description from questions order by id;
declare curs2 cursor for select description from answers where question_id = qid;
declare continue handler for not found set finito = 1;
-- drop table if exists tmp;
select count(*) as num into @cnt from answers group by question_id order by num desc limit 1;
drop table if exists tmp;
while i <= @cnt do
set str = concat(str,'answer',i,' varchar(10),');
set i = i + 1;
end while;
set str = substr(str,1,char_length(str)-1);
set @str = concat('create temporary table tmp (id int,question varchar(200),',str,');');
prepare stmt from @str;
execute stmt;
deallocate prepare stmt;
open curs1;
mio_loop:loop
fetch curs1 into qid,qdescription;
if finito = 1 then
close curs1;
leave mio_loop;
end if;
open curs2;
set str2 = 'insert into tmp (id,question,';
set j = 1;
set str3 = '';
mio_loop2:loop
fetch curs2 into qanswer;
if finito = 1 then set finito = 0;
close curs2;
leave mio_loop2;
end if;
set str2 = concat(str2,'answer',j,',');
set str3 = concat(str3,"'",qanswer,"',");
set j = j + 1;
end loop mio_loop2;
set str2 = substr(str2,1,char_length(str2)-1);
set str3 = substr(str3,1,char_length(str3)-1);
set @str2 = concat(str2,') values (',qid,",'",qdescription,"',",str3,');');
prepare stmt from @str2;
execute stmt;
deallocate prepare stmt;
end loop mio_loop;
select * from tmp;
end; //
delimiter ;
을하고 내가 그것을 호출 할 때 나는이 출력
mysql> call dynamic_view();
+------+------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
| id | question | answer1 | answer2 | answer3 | answer4 | answer5 | answer6 | answer7 | answer8 | answer9 |
+------+------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
| 1 | Question 1 | no | no | yes | no | yes | NULL | NULL | NULL | NULL |
| 2 | Question 2 | no | yes | yes | yes | no | no | no | yes | no |
| 3 | Question 3 | no | no | no | yes | NULL | NULL | NULL | NULL | NULL |
+------+------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
3 rows in set (0.23 sec)
이제
의 난 = 2 question_id 한 기록을 삭제하는 것이 가정하자를 얻을. 최대 레코드 수가 9 인 ID입니다. 삭제하면 레코드가 8이되므로 마지막 열이 사라져야합니다. 내가 다시 저장 프로 시저의 전체 코드를 실행하는 경우, 그러나
Error Code : 1054
Unknown column 'pivot.tmp.answer9' in 'field list'
후 나는 내가 올바른 결과를 얻을 리콜 : 내 SP를 호출하면
delete from answers where id = 14;
나는이 오류가
mysql> call dynamic_view();
+------+------------+---------+---------+---------+---------+---------+---------+---------+---------+
| id | question | answer1 | answer2 | answer3 | answer4 | answer5 | answer6 | answer7 | answer8 |
+------+------------+---------+---------+---------+---------+---------+---------+---------+---------+
| 1 | Question 1 | no | no | yes | no | yes | NULL | NULL | NULL |
| 2 | Question 2 | no | yes | yes | yes | no | no | no | yes |
| 3 | Question 3 | no | no | no | yes | NULL | NULL | NULL | NULL |
+------+------------+---------+---------+---------+---------+---------+---------+---------+---------+
3 rows in set (0.19 sec)
임시 테이블을 삭제 한 이유를 이해할 수 없습니다. 미리 감사드립니다. 편집하십시오. 현상금을 시작하고 싶었지만 버튼을 찾지 못했습니다. :)
저는 2 일 후에 만 현상금을 시작할 수 있다는 메타를 읽었습니다. 절대로 언급하지 않았습니다. 누군가가 나를 도울 수 있기를 바랍니다 :)
은 시저의 끝에서 TMP를 포기하려고? –
안녕하세요. 지금 당장 시도했다. 아무것도 바뀌지 않습니다. –
임시 테이블을 제대로 삭제할 수 없다고 생각됩니다. (연결을 끝내지 않고 자동으로 삭제하지 않고) tmp1, tmp2, tmp3과 같은 임시 테이블 이름을 사용하여 다른 임시 테이블을 만들어 다음 테이블의 이름을 추적하는 것이 좋습니다. 또한 필요할 때 저장 프로 시저가 재진입 될 수 있습니다. –