是否有任何替代方法用于存储过程而不是游标

时间:2013-10-04 12:43:44

标签: sql-server-2008 tsql cursor pivot common-table-expression

我使用游标,表变量和while循环

尝试了这个存储过程
DECLARE @High int
DECLARE @Medium int
DECLARE @Low int

Declare @CategoryName varchar(max)
Declare @tbRoles table(id int,Roles varchar(max))

insert into @tbRoles values(1,'Role1')
insert into @tbRoles values(2,'Role2')
insert into @tbRoles values(3,'Role3')

Declare  @tbAnswers table(Values varchar(max), Priority1 varchar(max), Priority2 varchar(max), Priority3 varchar(max))
Declare @ItemId table (Itemid int, CategoryName varchar(max)) 
Declare @Other table (Values varchar(max), Priority1 varchar(max), Priority2 varchar(max), Priority3 varchar(max))
Declare @temp table(SessionId varchar(max),ItemID_FK int,CategoryName varchar(max),Answer varchar(max),Roles varchar(max))
Declare @temp1 table(SessionId varchar(max),ItemID_FK int,CategoryName varchar(max),Answer varchar(max),Roles varchar(max))

insert into @ItemId
select ItemID_PK, CategoryName from [dbo].[tbl_Items] where ID_FK=4
Declare @Role varchar(max)
Declare @ItemId1 int
Declare @Item varchar(max)

DECLARE @i int = 1
WHILE @i <= 7  BEGIN
select @Role=Roles from @tbRoles where id=@i

insert into @temp
select distinct SessionID, ItemID_FK, CategoryName,Answer, Roles FROM [dbo].[tbl_Answers] where ID_FK=4 and Roles=@Role
insert into @temp1
select distinct SessionID, ItemID_FK, CategoryName,Answer, Roles FROM [dbo].[tbl_Answers] where ID_FK=4 and Roles=@Role and ItemID_FK is null
insert into  @tbAnswers values('','','','')
insert into  @tbAnswers values(@Role+' Responses','High','Medium','Low')

Declare curValues CURSOR for Select ItemID_PK,ItemName from tbl_Items where ID_FK=4
open curValues
fetch next from curValues into @ItemId1,@Item
While @@FETCH_STATUS=0
begin
select @High = COUNT(Answer) from @temp where Answer='High' and ItemID_FK=@ItemId1
select @Medium =  COUNT(Answer) from @temp where Answer='Medium' and ItemID_FK=@ItemId1
select @Low =  COUNT(Answer) from @temp where Answer='Low' and ItemID_FK=@ItemId1
select @CategoryName= CategoryName from @ItemId where Itemid=@ItemId1

insert into  @tbAnswers values(@CategoryName,@High,@Medium,@Low)

fetch next from curValues into @ItemId1,@Item
end

CLOSE curValues
DEALLOCATE curValues
insert into @tbAnswers values('Other',' ',' ',' ')
Declare curCounts CURSOR for Select CategoryName from tbl_Answers where ID_FK=4 and ItemID_FK is null and Roles=@Role
open curCounts
fetch next from curCounts into @Item
While @@FETCH_STATUS=0
begin
select @High = COUNT(Answer) from @temp1 where Answer='High' and ItemID_FK is null and CategoryName=@Item
select @Medium =  COUNT(Answer) from @temp1 where Answer='Medium' and SurveyItemID_FK is null and CategoryName=@Item
select @Low=  COUNT(SurveyAnswer) from @temp1 where SurveyAnswer='Low' and SurveyItemID_FK is null and SurveyCategoryName=@Item
set @CategoryName=@Item 
insert into @tbBoard values(@CategoryName,@High,@Medium,@Low)

fetch next from curSurvey into @Item
end

CLOSE curSurvey 
DEALLOCATE curSurvey
delete from @temp1
delete from @temp  
SET @i = @i + 1
end


select * from  @tbAnswers

获得这样的输出

+---------------+----------+----------+----------+
|Values         |Priority1 |Priority2 |Priority3 |
+---------------+----------+----------+----------+
|               |          |          |          |
+---------------+----------+----------+----------+
|Role1 Responses|High      |Low       |Medium    |
+---------------+----------+----------+----------+
| val1          | 5        | 8        | 4        |
+---------------+----------+----------+----------+
| val2          | 2        | 1        | 7        |
+---------------+----------+----------+----------+
| val3          | 9        | 0        | 4        |
+---------------+----------+----------+----------+
| OtherText     |          |          |          |
+---------------+----------+----------+----------+
| aaaa          | 9        | 2        | 4        |
+---------------+----------+----------+----------+
|               |          |          |          |
+---------------+----------+----------+----------+
|Role2 Responses|High      |Low       |Medium    |
+---------------+----------+----------+----------+
| val1          | 5        | 8        | 4        |
+---------------+----------+----------+----------+
| val2          | 2        | 1        | 7        |
+---------------+----------+----------+----------+
| val3          | 9        | 0        | 4        |
+---------------+----------+----------+----------+
| OtherText     |          |          |          |
+---------------+----------+----------+----------+
| xxx           | 9        | 2        | 4        |
+---------------+----------+----------+----------+
| yyy           |          |          |          |
+---------------+----------+----------+----------+
|               |          |          |          |
+---------------+----------+----------+----------+
|Role3 Responses|High      |Low       |Medium    |
+---------------+----------+----------+----------+
| val1          | 5        | 8        | 4        |
+---------------+----------+----------+----------+
| val2          | 2        | 1        | 7        |
+---------------+----------+----------+----------+
| val3          | 9        | 0        | 4        |
+---------------+----------+----------+----------+
| OtherText     |          |          |          |
+---------------+----------+----------+----------+

有些人定义光标会降低性能。是否有其他方法可以获得上述输出?

1 个答案:

答案 0 :(得分:0)

将第一个光标替换为:

insert into  @tbAnswers (CategoryName,High,Medium,Low)
select CategoryName,sum(case when Answer = 'High' then 1 else 0 end) as High
sum(case when Answer = 'Medium' then 1 else 0 end) as Medium
sum(case when Answer = 'Low' then 1 else 0 end) as Low
FROM @temp

您可以对第二个光标使用相同的技术。