SQL语句优化- while循环使用
在写一个报表的过程中,需要人员,工号,按日期汇总小时数
方案一:case when 转置
方案二:临时表
现在讨论方案二:
Create Procedure UF_Web_OTReportSp(
@Startingdatedatetime
,@Dept varchar(30)
)
AS
declare @ReportSet table(
id int IDENTITY (1, 1) NOT NULL,
name varchar(30),
workno varchar(20),
dept varchar(20),
d1 decimal(8,2),
d2 decimal(8,2),
d3 decimal(8,2),
d4 decimal(8,2),
d5 decimal(8,2),
d6 decimal(8,2),
d7 decimal(8,2),
d8 decimal(8,2),
d9 decimal(8,2),
d10 decimal(8,2),
d11 decimal(8,2),
d12 decimal(8,2),
d13 decimal(8,2),
d14 decimal(8,2),
d15 decimal(8,2),
d16 decimal(8,2),
d17 decimal(8,2),
d18 decimal(8,2),
d19 decimal(8,2),
d20 decimal(8,2),
d21 decimal(8,2),
d22 decimal(8,2),
d23 decimal(8,2),
d24 decimal(8,2),
d25 decimal(8,2),
d26 decimal(8,2),
d27 decimal(8,2),
d28 decimal(8,2),
d29 decimal(8,2),
d30 decimal(8,2),
d31 decimal(8,2),
ref varchar(30)
)
--select dateadd(d,1,'2008-10-08')
--d1-d31
declare @sql nvarchar(4000),@i int
set @i=30
while(@i<=30)
set @sql=insert @ReportSet(name,workno,dept,
insert @ReportSet(name,workno,dept,d1)select Dp.Name,O.PersonNo,Dt.description,O.OverTime
from Overtime O left join DeptPerson Dp on O.PersonNo=Dp.PersonNo
left join Dept Dt on Dp.DeptID=Dt.ID
where convert(varchar(10),O.TaskDate,120)=convert(varchar(10),@Startingdate,120)
insert @ReportSet(name,workno,dept,d2)select Dp.Name,O.PersonNo,Dt.description,O.OverTime
from Overtime O left join DeptPerson Dp on O.PersonNo=Dp.PersonNo
left join Dept Dt on Dp.DeptID=Dt.ID
where convert(varchar(10),O.TaskDate,120)=convert(varchar(10),dateadd(d,1,@Startingdate),120)
insert @ReportSet(name,workno,dept,d3)select Dp.Name,O.PersonNo,Dt.description,O.OverTime
from Overtime O left join DeptPerson Dp on O.PersonNo=Dp.PersonNo
left join Dept Dt on Dp.DeptID=Dt.ID
where convert(varchar(10),O.TaskDate,120)=convert(varchar(10),dateadd(d,2,@Startingdate),120)
insert @ReportSet(name,workno,dept,d4)select Dp.Name,O.PersonNo,Dt.description,O.OverTime
from Overtime O left join DeptPerson Dp on O.PersonNo=Dp.PersonNo
left join Dept Dt on Dp.DeptID=Dt.ID
where convert(varchar(10),O.TaskDate,120)=convert(varchar(10),dateadd(d,3,@Startingdate),120)
insert @ReportSet(name,workno,dept,d5)select Dp.Name,O.PersonNo,Dt.description,O.OverTime
from Overtime O left join DeptPerson Dp on O.PersonNo=Dp.PersonNo
left join Dept Dt on Dp.DeptID=Dt.ID
where convert(varchar(10),O.TaskDate,120)=convert(varchar(10),dateadd(d,4,@Startingdate),120)
insert @ReportSet(name,workno,dept,d6)select Dp.Name,O.PersonNo,Dt.description,O.OverTime
from Overtime O left join DeptPerson Dp on O.PersonNo=Dp.PersonNo
left join Dept Dt on Dp.DeptID=Dt.ID
where convert(varchar(10),O.TaskDate,120)=convert(varchar(10),dateadd(d,5,@Startingdate),120)
insert @ReportSet(name,workno,dept,d7)select Dp.Name,O.PersonNo,Dt.description,O.OverTime
from Overtime O left join DeptPerson Dp on O.PersonNo=Dp.PersonNo
left join Dept Dt on Dp.DeptID=Dt.ID
where convert(varchar(10),O.TaskDate,120)=convert(varchar(10),dateadd(d,6,@Startingdate),120)
insert @ReportSet(name,workno,dept,d8)select Dp.Name,O.PersonNo,Dt.description,O.OverTime
from Overtime O left join DeptPerson Dp on O.PersonNo=Dp.PersonNo
left join Dept Dt on Dp.DeptID=Dt.ID
where convert(varchar(10),O.TaskDate,120)=convert(varchar(10),dateadd(d,7,@Startingdate),120)
insert @ReportSet(name,workno,dept,d9)select Dp.Name,O.PersonNo,Dt.description,O.OverTime
from Overtime O left join DeptPerson Dp on O.PersonNo=Dp.PersonNo
left join Dept Dt on Dp.DeptID=Dt.ID
where convert(varchar(10),O.TaskDate,120)=convert(varchar(10),dateadd(d,8,@Startingdate),120)
insert @ReportSet(name,workno,dept,d10)select Dp.Name,O.PersonNo,Dt.description,O.OverTime
from Overtime O left join DeptPerson Dp on O.PersonNo=Dp.PersonNo
left join Dept Dt on Dp.DeptID=Dt.ID
where convert(varchar(10),O.TaskDate,120)=convert(varchar(10),dateadd(d,9,@Startingdate),120)
insert @ReportSet(name,workno,dept,d11)select Dp.Name,O.PersonNo,Dt.description,O.OverTime
from Overtime O left join DeptPerson Dp on O.PersonNo=Dp.PersonNo
left join Dept Dt on Dp.DeptID=Dt.ID
where convert(varchar(10),O.TaskDate,120)=convert(varchar(10),dateadd(d,10,@Startingdate),120)
insert @ReportSet(name,workno,dept,d12)select Dp.Name,O.PersonNo,Dt.description,O.OverTime
from Overtime O left join DeptPerson Dp on O.PersonNo=Dp.PersonNo
left join Dept Dt on Dp.DeptID=Dt.ID
where convert(varchar(10),O.TaskDate,120)=convert(varchar(10),dateadd(d,11,@Startingdate),120)
insert @ReportSet(name,workno,dept,d13)select Dp.Name,O.PersonNo,Dt.description,O.OverTime
from Overtime O left join DeptPerson Dp on O.PersonNo=Dp.PersonNo
left join Dept Dt on Dp.DeptID=Dt.ID
where convert(varchar(10),O.TaskDate,120)=convert(varchar(10),dateadd(d,12,@Startingdate),120)
insert @ReportSet(name,workno,dept,d14)select Dp.Name,O.PersonNo,Dt.description,O.OverTime
from Overtime O left join DeptPerson Dp on O.PersonNo=Dp.PersonNo
left join Dept Dt on Dp.DeptID=Dt.ID
where convert(varchar(10),O.TaskDate,120)=convert(varchar(10),dateadd(d,13,@Startingdate),120)
insert @ReportSet(name,workno,dept,d15)select Dp.Name,O.PersonNo,Dt.description,O.OverTime
from Overtime O left join DeptPerson Dp on O.PersonNo=Dp.PersonNo
left join Dept Dt on Dp.DeptID=Dt.ID
where convert(varchar(10),O.TaskDate,120)=convert(varchar(10),dateadd(d,14,@Startingdate),120)
insert @ReportSet(name,workno,dept,d16)select Dp.Name,O.PersonNo,Dt.description,O.OverTime
from Overtime O left join DeptPerson Dp on O.PersonNo=Dp.PersonNo
left join Dept Dt on Dp.DeptID=Dt.ID
where convert(varchar(10),O.TaskDate,120)=convert(varchar(10),dateadd(d,15,@Startingdate),120)
insert @ReportSet(name,workno,dept,d17)select Dp.Name,O.PersonNo,Dt.description,O.OverTime
from Overtime O left join DeptPerson Dp on O.PersonNo=Dp.PersonNo
left join Dept Dt on Dp.DeptID=Dt.ID
where convert(varchar(10),O.TaskDate,120)=convert(varchar(10),dateadd(d,16,@Startingdate),120)
insert @ReportSet(name,workno,dept,d18)select Dp.Name,O.PersonNo,Dt.description,O.OverTime
from Overtime O left join DeptPerson Dp on O.PersonNo=Dp.PersonNo
left join Dept Dt on Dp.DeptID=Dt.ID
where convert(varchar(10),O.TaskDate,120)=convert(varchar(10),dateadd(d,17,@Startingdate),120)
insert @ReportSet(name,workno,dept,d19)select Dp.Name,O.PersonNo,Dt.description,O.OverTime
from Overtime O left join DeptPerson Dp on O.PersonNo=Dp.PersonNo
left join Dept Dt on Dp.DeptID=Dt.ID
where convert(varchar(10),O.TaskDate,120)=convert(varchar(10),dateadd(d,18,@Startingdate),120)
insert @ReportSet(name,workno,dept,d20)select Dp.Name,O.PersonNo,Dt.description,O.OverTime
from Overtime O left join DeptPerson Dp on O.PersonNo=Dp.PersonNo
left join Dept Dt on Dp.DeptID=Dt.ID
where convert(varchar(10),O.TaskDate,120)=convert(varchar(10),dateadd(d,19,@Startingdate),120)
insert @ReportSet(name,workno,dept,d21)select Dp.Name,O.PersonNo,Dt.description,O.OverTime
from Overtime O left join DeptPerson Dp on O.PersonNo=Dp.PersonNo
left join Dept Dt on Dp.DeptID=Dt.ID
where convert(varchar(10),O.TaskDate,120)=convert(varchar(10),dateadd(d,20,@Startingdate),120)
insert @ReportSet(name,workno,dept,d22)select Dp.Name,O.PersonNo,Dt.description,O.OverTime
from Overtime O left join DeptPerson Dp on O.PersonNo=Dp.PersonNo
left join Dept Dt on Dp.DeptID=Dt.ID
where convert(varchar(10),O.TaskDate,120)=convert(varchar(10),dateadd(d,21,@Startingdate),120)
insert @ReportSet(name,workno,dept,d23)select Dp.Name,O.PersonNo,Dt.description,O.OverTime
from Overtime O left join DeptPerson Dp on O.PersonNo=Dp.PersonNo
left join Dept Dt on Dp.DeptID=Dt.ID
where convert(varchar(10),O.TaskDate,120)=convert(varchar(10),dateadd(d,22,@Startingdate),120)
insert @ReportSet(name,workno,dept,d24)select Dp.Name,O.PersonNo,Dt.description,O.OverTime
from Overtime O left join DeptPerson Dp on O.PersonNo=Dp.PersonNo
left join Dept Dt on Dp.DeptID=Dt.ID
where convert(varchar(10),O.TaskDate,120)=convert(varchar(10),dateadd(d,23,@Startingdate),120)
insert @ReportSet(name,workno,dept,d25)select Dp.Name,O.PersonNo,Dt.description,O.OverTime
from Overtime O left join DeptPerson Dp on O.PersonNo=Dp.PersonNo
left join Dept Dt on Dp.DeptID=Dt.ID
where convert(varchar(10),O.TaskDate,120)=convert(varchar(10),dateadd(d,24,@Startingdate),120)
insert @ReportSet(name,workno,dept,d26)select Dp.Name,O.PersonNo,Dt.description,O.OverTime
from Overtime O left join DeptPerson Dp on O.PersonNo=Dp.PersonNo
left join Dept Dt on Dp.DeptID=Dt.ID
where convert(varchar(10),O.TaskDate,120)=convert(varchar(10),dateadd(d,25,@Startingdate),120)
insert @ReportSet(name,workno,dept,d27)select Dp.Name,O.PersonNo,Dt.description,O.OverTime
from Overtime O left join DeptPerson Dp on O.PersonNo=Dp.PersonNo
left join Dept Dt on Dp.DeptID=Dt.ID
where convert(varchar(10),O.TaskDate,120)=convert(varchar(10),dateadd(d,26,@Startingdate),120)
insert @ReportSet(name,workno,dept,d28)select Dp.Name,O.PersonNo,Dt.description,O.OverTime
from Overtime O left join DeptPerson Dp on O.PersonNo=Dp.PersonNo
left join Dept Dt on Dp.DeptID=Dt.ID
where convert(varchar(10),O.TaskDate,120)=convert(varchar(10),dateadd(d,27,@Startingdate),120)
insert @ReportSet(name,workno,dept,d29)select Dp.Name,O.PersonNo,Dt.description,O.OverTime
from Overtime O left join DeptPerson Dp on O.PersonNo=Dp.PersonNo
left join Dept Dt on Dp.DeptID=Dt.ID
where convert(varchar(10),O.TaskDate,120)=convert(varchar(10),dateadd(d,28,@Startingdate),120)
insert @ReportSet(name,workno,dept,d30)select Dp.Name,O.PersonNo,Dt.description,O.OverTime
from Overtime O left join DeptPerson Dp on O.PersonNo=Dp.PersonNo
left join Dept Dt on Dp.DeptID=Dt.ID
where convert(varchar(10),O.TaskDate,120)=convert(varchar(10),dateadd(d,29,@Startingdate),120)
insert @ReportSet(name,workno,dept,d31)select Dp.Name,O.PersonNo,Dt.description,O.OverTime
from Overtime O left join DeptPerson Dp on O.PersonNo=Dp.PersonNo
left join Dept Dt on Dp.DeptID=Dt.ID
where convert(varchar(10),O.TaskDate,120)=convert(varchar(10),dateadd(d,30,@Startingdate),120)
select * from @ReportSet
//这样的代码冗余
就想到优化
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[UF_Web_OTReportSp]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
drop procedure [dbo].[UF_Web_OTReportSp]
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_NULLS ON
GO
Create Procedure UF_Web_OTReportSp(
@Startingdatedatetime=null
,@Dept varchar(30)=null
)
AS
declare @sql nvarchar(4000),@i char(2),@j char(2),@date nvarchar(10)
set @i='1'
set @j='0'
set @date=convert(varchar(10),@Startingdate,120)
declare @ReportSet table(
id int IDENTITY (1, 1) NOT NULL,
name varchar(30),
workno varchar(20),
dept varchar(20),
d1 decimal(8,2),
d2 decimal(8,2),
d3 decimal(8,2),
d4 decimal(8,2),
d5 decimal(8,2),
d6 decimal(8,2),
d7 decimal(8,2),
d8 decimal(8,2),
d9 decimal(8,2),
d10 decimal(8,2),
d11 decimal(8,2),
d12 decimal(8,2),
d13 decimal(8,2),
d14 decimal(8,2),
d15 decimal(8,2),
d16 decimal(8,2),
d17 decimal(8,2),
d18 decimal(8,2),
d19 decimal(8,2),
d20 decimal(8,2),
d21 decimal(8,2),
d22 decimal(8,2),
d23 decimal(8,2),
d24 decimal(8,2),
d25 decimal(8,2),
d26 decimal(8,2),
d27 decimal(8,2),
d28 decimal(8,2),
d29 decimal(8,2),
d30 decimal(8,2),
d31 decimal(8,2),
ref varchar(30)
)
--select dateadd(d,1,'2008-10-08')
--d1-d31
while @i<=30
begin
set @sql='insert @ReportSet (name,workno,dept,d'+@i+')select Dp.Name,O.PersonNo,Dt.description,O.OverTime
from Overtime O left join DeptPerson Dp on O.PersonNo=Dp.PersonNo
left join Dept Dt on Dp.DeptID=Dt.ID
where convert(varchar(10),O.TaskDate,120)=convert(varchar(10),dateadd(d,'
+@j+','''+@date+'''),120)'
set @i=@i+1
set @j=@j+1
exec(@sql)
end
select *
from @ReportSet
测试结果:
无法没有申明@ReportSet,可确实已经申明。查询错误:
CSDN的提示:
你是不是执行动态SQL语句哦,动态SQL语句中使用使用表名,要用字符串变量来存储表名,如nvarchar(100),不能直接使用表变量.
declare @accounts table (
account_id numeric(10,0) not null primary key)
create table #accounts (
account_id numeric(10,0) not null primary key)
故采用临时表的概念加入动态SQL
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[UF_Web_OTReportSp]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
drop procedure [dbo].[UF_Web_OTReportSp]
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_NULLS ON
GO
Create Procedure UF_Web_OTReportSp(
@Startingdatedatetime=null
,@Dept varchar(30)=null
)
AS
declare @sql nvarchar(4000),@i char(2),@j char(2),@date nvarchar(10)
set @i='1'
set @j='0'
set @date=convert(varchar(10),@Startingdate,120)
create table #ReportSet (
id int IDENTITY (1, 1) NOT NULL,
name varchar(30),
workno varchar(20),
dept varchar(20),
d1 decimal(8,2),
d2 decimal(8,2),
d3 decimal(8,2),
d4 decimal(8,2),
d5 decimal(8,2),
d6 decimal(8,2),
d7 decimal(8,2),
d8 decimal(8,2),
d9 decimal(8,2),
d10 decimal(8,2),
d11 decimal(8,2),
d12 decimal(8,2),
d13 decimal(8,2),
d14 decimal(8,2),
d15 decimal(8,2),
d16 decimal(8,2),
d17 decimal(8,2),
d18 decimal(8,2),
d19 decimal(8,2),
d20 decimal(8,2),
d21 decimal(8,2),
d22 decimal(8,2),
d23 decimal(8,2),
d24 decimal(8,2),
d25 decimal(8,2),
d26 decimal(8,2),
d27 decimal(8,2),
d28 decimal(8,2),
d29 decimal(8,2),
d30 decimal(8,2),
d31 decimal(8,2),
ref varchar(30)
)
--select dateadd(d,1,'2008-10-08')
--d1-d31
while @i<=30
begin
set @sql='insert #ReportSet (name,workno,dept,d'+@i+')select Dp.Name,O.PersonNo,Dt.description,O.OverTime
from Overtime O left join DeptPerson Dp on O.PersonNo=Dp.PersonNo
left join Dept Dt on Dp.DeptID=Dt.ID
where convert(varchar(10),O.TaskDate,120)=convert(varchar(10),dateadd(d,'
+@j+','''+@date+'''),120)'
+'and isnull(Dt.description,1)=' +case when @Dept is null then 'isnull(Dt.description,1)' else ''''+@Dept+'''' end
set @i=@i+1
set @j=@j+1
exec(@sql)
end
select workno,
name,
dept,
isnull(sum(d1),0) as d1,
isnull(sum(d2),0) as d2,
isnull(sum(d3),0) as d3,
isnull(sum(d4),0) as d4,
isnull(sum(d5),0) as d5,
isnull(sum(d6),0) as d6,
isnull(sum(d7),0) as d7,
isnull(sum(d8),0) as d8,
isnull(sum(d9),0) as d9,
isnull(sum(d10),0) as d10,
isnull(sum(d11),0) as d11,
isnull(sum(d12),0) as d12,
isnull(sum(d13),0) as d13,
isnull(sum(d14),0) as d14,
isnull(sum(d15),0) as d15,
isnull(sum(d16),0) as d16,
isnull(sum(d17),0) as d17,
isnull(sum(d18),0) as d18,
isnull(sum(d19),0) as d19,
isnull(sum(d20),0) as d20,
isnull(sum(d21),0) as d21,
isnull(sum(d22),0) as d22,
isnull(sum(d23),0) as d23,
isnull(sum(d24),0) as d24,
isnull(sum(d25),0) as d25,
isnull(sum(d26),0) as d26,
isnull(sum(d27),0) as d27,
isnull(sum(d28),0) as d28,
isnull(sum(d29),0) as d29,
isnull(sum(d30),0) as d30,
isnull(sum(d31),0) as d31
from #ReportSet
group by workno,name,dept