设为首页 收藏本站
查看: 867|回复: 0

[经验分享] 一个Excel导入SQL Server的例子

[复制链接]

尚未签到

发表于 2016-11-1 10:03:53 | 显示全部楼层 |阅读模式

有人提问如下:


这个是Excel的,比如是test.xls

欠费年份 欠费开始月份 欠费结束月份 应缴金额(月租)

2001 9 12 94.4

2008 5 12 88.8

2010 8 12 90.4

___________________________________________


这个是表:比如是a表

a(pk,int,not null) //主键,自动增长

b(varchar(19),null)
//费款所属期

c(decimal(10,2),null) //应缴金额___________________________________________


现在我要将test.xls中的数据导入到a表,从开始月份到结束月份要做循环导入,比如第一条2001年的从9月到12月要录入4条数据到a表,导入后的格式如:

select * from a


a b c

1 2001-09 94.4

2 2001-10 94.4

3 2001-11 94.4

4 2001-12 94.4


数据库是:MS Sql server 2008


--启用Ad Hoc Distributed Queries:
exec sp_configure 'show advanced options',1
reconfigure
exec sp_configure 'Ad Hoc Distributed Queries',1
reconfigure

--使用完成后,关闭Ad Hoc Distributed Queries:
exec sp_configure 'Ad Hoc Distributed Queries',0
reconfigure
exec sp_configure 'show advanced options',0
reconfigure


解析:


思路一:可以使用OpenRowset查询导入到表变量中,再用游标循环赋值。方法如下:


DSC0000.gif

use testdb2
go
/*******************建立测试数据***3w@live.cn***********************/
IF NOT OBJECT_ID('[TBTest]') IS NULL
DROP TABLE [TBTest]
GO
CREATE TABLE [TBTest](
[tid] int identity(1,1) primary key,
[date] NVARCHAR(20) null,
[Money] decimal(10,2) null)
go
/*******************启用Ad Hoc Distributed Queries***3w@live.cn***********************/
--------USE master
--
------go
--
------sp_configure 'show advanced options', 1
--
------GO
--
----------reconfigure
--
--------启用分布式查询 Ad Hoc Distributed Queries
--
------sp_configure 'Ad Hoc Distributed Queries', 1
--
------GO
--
------reconfigure
--
------go
use testdb2
go
/*******************定义表变量***3w@live.cn***********************/
Declare @TableVar table
(PKId
int primary key identity(1,1)
,RYear
int not null,BMonth int not null
,EMonth
int not null,RMoney Decimal(15,2) not null
)
insert into @TableVar
(RYear ,BMonth ,EMonth ,RMoney)
select * from OpenRowSet('Microsoft.Jet.OLEDB.4.0',
'Excel 8.0;HDR=Yes;IMEX=1;Database=D:/test/test20110501.xls',
'select * from [Sheet1$]')
----select RYear,BMonth,EMonth,RMoney from @TableVar
--
----update @TableVar
--
----SET d1=cast(
--
----Cast(RYear as Nvarchar(4))+'-'+cast(BMonth AS nvarchar(2))+'-01' as date)
--
----, d2=cast(
--
----Cast(RYear as Nvarchar(4))+'-'+cast(EMonth AS nvarchar(2))+'-01' as date)
/*
******************第一种方法,用游标***3w@live.cn***********************/
DECLARE @RYear int
declare @BMonth int
declare @EMonth int
declare @RMoney int
DECLARE DateDemo_cursor CURSOR FOR
select RYear,BMonth,EMonth,RMoney from @TableVar where 1=1
OPEN DateDemo_cursor
FETCH NEXT FROM DateDemo_cursor
INTO @RYear,@BMonth,@EMonth,@RMoney
WHILE @@FETCH_STATUS = 0
BEGIN
--修改记录
while(@EMonth-@BMonth>=0)
begin
insert INTO [TBTest]
SELECT TOP 1 cast(RYear  AS nvarchar(4))+'-'+
CASE WHEN (@BMonth<10) THEN '0'+cast(@BMonth AS nvarchar(2))
ELSE cast(@BMonth AS nvarchar(2)) END,
Rmoney
from @TableVar where Ryear=@RYear
SET @BMonth=@BMonth+1
end
--修改结束
FETCH NEXT FROM DateDemo_cursor into @RYear,@BMonth,@EMonth,@RMoney
END
CLOSE DateDemo_cursor
DEALLOCATE DateDemo_cursor
GO
SELECT * FROM [TBTest]





查询结果:




/*

tid date Money

1 2001-09 94.40

2 2001-10 94.40

3 2001-11 94.40

4 2001-12 94.40

5 2008-05 88.80

6 2008-06 88.80

7 2008-07 88.80

8 2008-08 88.80

9 2008-09 88.80

10 2008-10 88.80

11 2008-11 88.80

12 2008-12 88.80

13 2010-08 90.40

14 2010-09 90.40

15 2010-10 90.40

16 2010-11 90.40

17 2010-12 90.40
*/







评价:该方法使用了最传统的方法,思路清晰。但没有体现SQL server 2008的语法特性,略显繁琐。


思路二:可否使用CTE实现?(KillKill提供)




/*******************第二种方法,用CTE,适用于sql2005/2008/2008 r2*********/
/***************************************3w@live.cn***********************/
TRUNCATE table [TBTest]
go
Declare @TableVar table
(PKId
int primary key identity(1,1)
,RYear
int not null,BMonth int not null
,EMonth
int not null,RMoney Decimal(15,2) not null
);
insert into @TableVar(RYear ,BMonth ,EMonth ,RMoney)
select * from OpenRowSet('Microsoft.Jet.OLEDB.4.0',
'Excel 8.0;HDR=Yes;IMEX=1;Database=D:/test/test20110501.xls',
'select * from [Sheet1$]');

with seq as (select top 12 row_number() over (order by object_id) val
from sys.objects)
select
cast(t.RYear  AS nvarchar(4))+'-'+
CASE WHEN (t.BMonth+seq.val<10) THEN '0'+cast(t.BMonth+seq.val AS nvarchar(2))
ELSE cast(t.BMonth+seq.val AS nvarchar(2)) END
,RMoney c
from @TableVar t inner join seq
on t.BMonth+seq.val <= EMonth;







思路三:可否使用SQL Server 2008新提供的Merge实现?


思路四:使用NPOI在业务层实现数据转换。


思路五:用Master..spt_values表实现(由小F提供)


利用该表,可获取一定区间内的列表,最长不超过2048,如




select number from master..spt_values
where type='P' and
number between 1 and 5
/*
number
1
2
3
4
5
*/







因为月份最多12,不超过2048,因此可以利用 master..spt_values。




/*******************第五种方法,用master..spt_values,适用于sql2005/2008/2008 r2*********/
/***************************************3w@live.cn***********************/
Declare @TableVar table
(PKId
int primary key identity(1,1)
,RYear
int not null,BMonth int not null
,EMonth
int not null,RMoney Decimal(15,2) not null
----,d1 date null,d2 Date null
);
insert into @TableVar
(RYear ,BMonth ,EMonth ,RMoney)
select * from OpenRowSet('Microsoft.Jet.OLEDB.4.0',
'Excel 8.0;HDR=Yes;IMEX=1;Database=D:/test/test20110501.xls',
'select * from [Sheet1$]');
select
tid
=row_number()over(order by getdate()),ltrim(RYear)+'-'+ltrim(right(100+number,2)) as date,
     b.RMoney
as money
from
master..spt_values a,
@TableVar b
where
number between BMonth and EMonth
and
type
='p'






运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-294166-1-1.html 上篇帖子: SQL Server 创建和使用索引 下篇帖子: Sql Server 导入 My Sql 遇到的一些问题 。。。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表