项目开发笔记(临时视图)-1
2006-05-25 11:09
302 查看
电信话单查询模块开发心得(临时视图的使用)
前个星期,在女友的关系介绍下,找到了项目,就是开发一个话单查询子系统,由于是电信级别的东西,数据量自然是大了,日数据量就有500万左右,听了都是吓人的(具体我也不清楚,因为是负责人说的).
项目拿到了,碰到的首要问题就是:如何跨多表查询?
例如:2006-5-1日的数据就存在 F_20050502中
2006-5-2日的数据就存在 F_20050502中
2006-5-3日的数据就存在 F_20050503中
依次类推...
而,用户查询的时候,又需要从多个表中查询数据.例如:查2006-5-1 到 2006-5-10的数据,就要跨10个表.(真的是很麻烦)
经过2天的思索,我想出了以下的方案.用存储过程实现,通过传入 start_time (起始时间) end_time(结束时间),用循环查询先确定表是否存在,然后动态生成一个 select 语句.用 union all 把这些个select语句组合在一起.代码如下:
declare @sd datetime
declare @ed datetime
declare @td datetime
declare @NN int
declare @d int
declare @sql varchar(4000)
declare @T varchar(255)
set @sd=@start_time--CAST('2006-05-01 12:35:29.998' AS datetime)
set @ed=@end_time --CAST('2006-05-03 12:35:29.998' AS datetime)
--set @td=@sd
set @d=datediff(DD,@sd,@ed)
print @d
print @td
set @NN=0
set @sql=' '
DECLARE @FLAG INT
SET @FLAG=0
-- 生成待查询的数据表 集合
while @NN<=@d
begin
set @td=dateadd(DD,@NN,@sd)
set @NN=@NN+1
SET @T=DATEPART(YYYY,@td)
if DATEPART(MM,@td)<10
set @T=@T+'0'+cast(DATEPART(MM,@td) as char(1))
else
set @T=@T+CAST(DATEPART(MM,@td) AS CHAR(2))
if DATEPART(DD,@td)<10
set @T=@T+'0'+cast(DATEPART(DD,@td) as char(1))
else
set @T=@T+CAST(DATEPART(DD,@td) AS CHAR(2))
SET @T='FACT_'+@T
--PRINT @T
if exists (select * from sysobjects where id = object_id(@T) and OBJECTPROPERTY(id, 'IsUserTable') = 1)
BEGIN
--PRINT '-----'
PRINT @T
--PRINT '!----!'
--考虑时间范围 小时/分
IF @FLAG=0
begin
SET @SQL='SELECT '+@fileds+' FROM '+@T+' where start_time>='''+cast(@start_time as varchar(50))+''' and '+@query
SET @FLAG=1
end
ELSE
begin
SET @SQL=@SQL+' UNION ALL SELECT '+@fileds+' FROM '+@T+' where '+@query
end
END
end
到此处,@SQL里,已经是多个表查询的语句了.再在外面套上一个 select 语句就可以查询.
如: @SQL='select * from ('+@SQL+')'就可以了
最后exec(@SQL)就可以返回数据了.
不过,经过实际运用,该方法不太好,生成的sql 语句太长,而且是用不方便.于是我又想出了第2种办法,就是"临时视图",为什么有"临时表"就不能有"临时视图"呢?
采用了该方法后,程序大大简化了.而且使用方便了,至于效率吗(机器效率)应该是低点.
具体思路是:
程序运行时,先确定范围,然后根据范围自动创建一个视图,提供给后续查询用,查询完毕后,用drop把视图删除.
具体如下
while @NN<=@d
begin
set @td=dateadd(DD,@NN,@sd)
set @NN=@NN+1
SET @T=DATEPART(YYYY,@td)
if DATEPART(MM,@td)<10
set @T=@T+'0'+cast(DATEPART(MM,@td) as char(1))
else
set @T=@T+CAST(DATEPART(MM,@td) AS CHAR(2))
if DATEPART(DD,@td)<10
set @T=@T+'0'+cast(DATEPART(DD,@td) as char(1))
else
set @T=@T+CAST(DATEPART(DD,@td) AS CHAR(2))
SET @T='FACT_'+@T
--PRINT @T
if exists (select * from sysobjects where id = object_id(@T) and OBJECTPROPERTY(id, 'IsUserTable') = 1)
BEGIN
set @FLAG=@FLAG+1
IF @FLAG=1
begin
set @sql='select * from '+@T
end
ELSE
begin
set @sql=@sql+' union all select * from '+@t
end
END
end
if @FLAG=0
begin
select 0
return -1
end
--创建一个零时试图
declare @tmpView varchar(4000)
set @tmpView='tmpV'+cast(DATEPART(YYYY,getDate()) as varchar(4))+
cast(DATEPART(MM,getDate()) as varchar(2))+
cast(DATEPART(DD,getDate()) as varchar(2))+
cast(DATEPART(HH,getDate()) as varchar(2))+
cast(DATEPART(SS,getDate()) as varchar(2))+
cast(DATEPART(MS,getDate()) as varchar(4))
set @sql='CREATE VIEW '+@tmpView+ ' as '+@sql
print @sql
exec(@sql)
--临时视图创建完毕
到此视图@tmpView 就创建好了.后面的查询都可以直接引用 @tmpView了.
在查询结束后,只需要在执行下面的语句即可
set @sql='drop view '+@tmpView
exec(@sql)
前个星期,在女友的关系介绍下,找到了项目,就是开发一个话单查询子系统,由于是电信级别的东西,数据量自然是大了,日数据量就有500万左右,听了都是吓人的(具体我也不清楚,因为是负责人说的).
项目拿到了,碰到的首要问题就是:如何跨多表查询?
例如:2006-5-1日的数据就存在 F_20050502中
2006-5-2日的数据就存在 F_20050502中
2006-5-3日的数据就存在 F_20050503中
依次类推...
而,用户查询的时候,又需要从多个表中查询数据.例如:查2006-5-1 到 2006-5-10的数据,就要跨10个表.(真的是很麻烦)
经过2天的思索,我想出了以下的方案.用存储过程实现,通过传入 start_time (起始时间) end_time(结束时间),用循环查询先确定表是否存在,然后动态生成一个 select 语句.用 union all 把这些个select语句组合在一起.代码如下:
declare @sd datetime
declare @ed datetime
declare @td datetime
declare @NN int
declare @d int
declare @sql varchar(4000)
declare @T varchar(255)
set @sd=@start_time--CAST('2006-05-01 12:35:29.998' AS datetime)
set @ed=@end_time --CAST('2006-05-03 12:35:29.998' AS datetime)
--set @td=@sd
set @d=datediff(DD,@sd,@ed)
print @d
print @td
set @NN=0
set @sql=' '
DECLARE @FLAG INT
SET @FLAG=0
-- 生成待查询的数据表 集合
while @NN<=@d
begin
set @td=dateadd(DD,@NN,@sd)
set @NN=@NN+1
SET @T=DATEPART(YYYY,@td)
if DATEPART(MM,@td)<10
set @T=@T+'0'+cast(DATEPART(MM,@td) as char(1))
else
set @T=@T+CAST(DATEPART(MM,@td) AS CHAR(2))
if DATEPART(DD,@td)<10
set @T=@T+'0'+cast(DATEPART(DD,@td) as char(1))
else
set @T=@T+CAST(DATEPART(DD,@td) AS CHAR(2))
SET @T='FACT_'+@T
--PRINT @T
if exists (select * from sysobjects where id = object_id(@T) and OBJECTPROPERTY(id, 'IsUserTable') = 1)
BEGIN
--PRINT '-----'
PRINT @T
--PRINT '!----!'
--考虑时间范围 小时/分
IF @FLAG=0
begin
SET @SQL='SELECT '+@fileds+' FROM '+@T+' where start_time>='''+cast(@start_time as varchar(50))+''' and '+@query
SET @FLAG=1
end
ELSE
begin
SET @SQL=@SQL+' UNION ALL SELECT '+@fileds+' FROM '+@T+' where '+@query
end
END
end
到此处,@SQL里,已经是多个表查询的语句了.再在外面套上一个 select 语句就可以查询.
如: @SQL='select * from ('+@SQL+')'就可以了
最后exec(@SQL)就可以返回数据了.
不过,经过实际运用,该方法不太好,生成的sql 语句太长,而且是用不方便.于是我又想出了第2种办法,就是"临时视图",为什么有"临时表"就不能有"临时视图"呢?
采用了该方法后,程序大大简化了.而且使用方便了,至于效率吗(机器效率)应该是低点.
具体思路是:
程序运行时,先确定范围,然后根据范围自动创建一个视图,提供给后续查询用,查询完毕后,用drop把视图删除.
具体如下
while @NN<=@d
begin
set @td=dateadd(DD,@NN,@sd)
set @NN=@NN+1
SET @T=DATEPART(YYYY,@td)
if DATEPART(MM,@td)<10
set @T=@T+'0'+cast(DATEPART(MM,@td) as char(1))
else
set @T=@T+CAST(DATEPART(MM,@td) AS CHAR(2))
if DATEPART(DD,@td)<10
set @T=@T+'0'+cast(DATEPART(DD,@td) as char(1))
else
set @T=@T+CAST(DATEPART(DD,@td) AS CHAR(2))
SET @T='FACT_'+@T
--PRINT @T
if exists (select * from sysobjects where id = object_id(@T) and OBJECTPROPERTY(id, 'IsUserTable') = 1)
BEGIN
set @FLAG=@FLAG+1
IF @FLAG=1
begin
set @sql='select * from '+@T
end
ELSE
begin
set @sql=@sql+' union all select * from '+@t
end
END
end
if @FLAG=0
begin
select 0
return -1
end
--创建一个零时试图
declare @tmpView varchar(4000)
set @tmpView='tmpV'+cast(DATEPART(YYYY,getDate()) as varchar(4))+
cast(DATEPART(MM,getDate()) as varchar(2))+
cast(DATEPART(DD,getDate()) as varchar(2))+
cast(DATEPART(HH,getDate()) as varchar(2))+
cast(DATEPART(SS,getDate()) as varchar(2))+
cast(DATEPART(MS,getDate()) as varchar(4))
set @sql='CREATE VIEW '+@tmpView+ ' as '+@sql
print @sql
exec(@sql)
--临时视图创建完毕
到此视图@tmpView 就创建好了.后面的查询都可以直接引用 @tmpView了.
在查询结束后,只需要在执行下面的语句即可
set @sql='drop view '+@tmpView
exec(@sql)
相关文章推荐
- 项目开发笔记(临时视图)-1
- [Openwrt 项目开发笔记]:Openwrt平台搭建(一)
- PHP+MySQL项目开发——留言本开发笔记1
- 移动项目开发笔记(C#数字日期转换成中文日期(zt))
- 移动项目开发笔记(动态生成xml文件生成导航菜单(续))
- 某android平板项目开发笔记----aChartEngine图表显示(1)
- 开发笔记 视图管理 子视图切图和查询子视图
- [Openwrt 项目开发笔记]:Openwrt必要设置(二)
- Android开发学习笔记:浅谈DDMS视图
- 微信小程序开发学习笔记008--微信小程序项目02
- [学习笔记]Silverlight4 RIA 开发全程解析[项目全程记录]----第零章--项目简介
- SilverLight商业应用程序开发---学习笔记(9)从摘要信息跳转到详细信息 导航到细节视图 在弹出窗体打开细节视图 使用DataGrid控件的行细节显示特性显示细节内容 主/从视图的实现
- iOS项目开发实战——设置视图的透明度改变动画
- 没头没尾--项目开发笔记:面向业务的用户界面与面向对象的数据库如何连接
- Castle学习笔记----将Castle IOC引入项目开发中实现“依赖注入”
- ThinkPHP开发笔记-视图
- 项目开发笔记
- [Openwrt 项目开发笔记]:Openwrt必要设置(二)
- 斯坦福大学公开课 iOS应用开发教程学习笔记(第四课) Views 视图
- 某android平板项目开发笔记----aChartEngine图表显示(1)