1. 程式人生 > >實驗9-11 編寫一個存儲過程proc_test_stat4,統計用戶實驗情況

實驗9-11 編寫一個存儲過程proc_test_stat4,統計用戶實驗情況

實驗 答題 begin 經典的 語義 emp ebo 1.5 tin

轉自 毛琨同學

在TestDB數據庫中, 編寫一個存儲過程proc_test_stat4,統計用戶實驗情況,要求:

1)無參數

2)在數據庫中有表exercisebook, 用於保存用戶的作業,包含下列字段

exerid 作業的唯一編號;

quesid 問題編號

userid 用戶編號

eval 驗證結果:start,success,error

posttime 提交時間

其中,數據的語義是

a)用戶和問題是多對多關系,一個用戶在答題過程中對同一個問題會產生多條記錄;

b)驗證結果中的start表示開始實驗,success表示成功結束實驗,error表示驗證錯誤;

c)每個用戶開始實驗時會在exercisebook表中增加一條eval 內容是start的記錄,其中包含開始時間;

d)開始實驗後,每次提交都會在exercisebook表中增加一條記錄,如果驗證成功則eval 是success,若錯誤則eval 是error

e)如果在exercisebook表中沒有關於userid和quesid的記錄,則說明此用戶還沒有開始quesid的實驗。

為更直觀的觀察用戶的實驗完成狀態,請以用戶為行,問題為列(僅考慮exercisebook中的所有userid和quesid)返回最近一次的提交情況,形如下表:(NULL表示實驗未開始)


技術分享圖片

提示:這是經典的“行轉列”問題。可以使用遊標,也可以使用動態sql查詢實現。

測試語句:

exec proc_test_stat4

create proc proc_test_stat4
as
begin
set nocount on;
	create table #temp(
	exerid bigint,
	userid bigint,
	quesid bigint,
	eval varchar(7),
	posttime datetime
	)
	declare @exerid bigint,@userid bigint,@quesid bigint,
		@eval varchar(7),@posttime datetime
	declare cur cursor
	for select exerid,userid,quesid,eval,posttime from exercisebook
	open cur
	fetch next from cur
	into @exerid,@userid,@quesid,@eval,@posttime 
	while @@fetch_status=0
	begin
		if(not exists(select * from #temp where userid=@userid))
			insert into #temp(exerid,userid,quesid,eval,posttime)
			values(@exerid,@userid,@quesid,@eval,@posttime)
		else
			update #temp
			set exerid=@exerid,quesid=@quesid,eval=@eval,posttime=@posttime
			where userid=@userid and posttime<@posttime
		fetch next from cur
		into @exerid,@userid,@quesid,@eval,@posttime
	end 
	close cur
	deallocate cur

--行轉列--
declare @s nvarchar(4000)
select @s=isnull(@s+‘,‘,‘‘)+quotename(quesid)
from(select distinct quesid from #temp) as x

declare @sq nvarchar(4000)
set @sq=‘select b.* from #temp as a 
		pivot(max(a.eval) for a.quesid in(‘+@s+‘)) as b‘
exec(@sq)
set nocount off
end

  

實驗9-11 編寫一個存儲過程proc_test_stat4,統計用戶實驗情況