sqlserver中将存储过程中null转化为0_ACCESS向SQL SERVER后台去重插入10万条记录

cd731cf8d7d49f765e1f2d7ebf514b31.png

      因为在写考勤系统原先用的ACCESS 做为后台,改成SQL SERVER后读取6.5万行记录居然死机了?

      找了几天才找到原因,高频连接和UPDATA造成SQL SERVER 假锁死也就是后台不工作。测试不去重直接Update插入SQL SERVER,1分钟也才1万条记录,这性能和ACCESS一样了。ACCESS 又没有ADO.NET,只能从存储过程下手了。又学了几天总结出的方案:读取记录后每100条记录合并成一个VALUES值发放给后台存储过程执行去重插入。

      实测环境:WIN7/SQL SERVER 2008R2\4G内存\从ACCESS 读取6.5条记录去重插入目标表

      读取6.5万条记录用时:17秒。

      6.5万条记录完成读取和去重插入目标表用时:26秒。

      性能很完美了,因为从考勤机读取记录也需要耗费时间。

      在VBA代码里关闭和开启SQL日志,可以减少SQL日志的疯长。

      接收数据后直接插入临时表<#tmpCheckInOut> ,去重插入目标表<dbo.tblCheckInOut>  

      目标表和临时表的结构只多了一个ID

分享测试VBA代码和存储过程代码:

‘---------------ACCESS VBA 代码  -----------------

 Set SQLcnn =<SQL SERVER 连接语句>’自行在平台查找

SQLcnn.Execute "Alter DATABASE [DataSQL] SET RECOVERY simple"   ‘关闭SQL 日志

set rst=<10万行记录源连接>

rst.MoveFirst
    strSQL = ""
    lngj = 0
    Do While Not rst.EOF
        If strSQL = "" Then
            strSQL = "'("
        Else
            strSQL = strSQL & ",("
        End If
        strSQL = strSQL & rst.Fields("MachineNo")
        strSQL = strSQL & ",''" & rst.Fields("EnrollNo") & "''"
        strSQL = strSQL & "," & rst.Fields("dwVMode")
        strSQL = strSQL & "," & rst.Fields("dwIOMode")
        strSQL = strSQL & ",''" & Format(rst.Fields("dwalltime"), "yyyy-mm-dd hh:nn:ss") & "'')"
        lngj = lngj + 1
        If lngj = 100 Then ’每100行记录向SQL后台发送更新数据
            strSQL = "execute dbo.pro_Insert_UpdatetblCheckInOut " & strSQL & "'"
            SQLcnn.Execute strSQL
            lngj = 0
            strSQL = ""
        End If
        rst.MoveNext
    Loop
    If lngj < 100 And strSQL <> "" Then ’最后不足100行,记录向SQL后台发送更新数据
        strSQL = "execute dbo.pro_Insert_UpdatetblCheckInOut " & strSQL & "'"
        SQLcnn.Execute strSQL
        lngj = 0
        strSQL = ""
    End If
    SQLcnn.Execute "Alter DATABASE [DataSQL] SET RECOVERY bulk_logged" ‘开启SQL 日志

/*pro_Insert_UpdatetblCheckInOut存储过程代码:

接收数据后直接插入临时表<#tmpCheckInOut> ,去重插入目标表<dbo.tblCheckInOut>  */

USE [DataSQL]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
Create proc [dbo].[pro_Insert_UpdatetblCheckInOut]
@intoCheckvalues varchar(7000)
as--创建临时表
IF EXISTS(select * from tempdb..sysobjects where id=object_id('tempdb..#tmpcheckinout'))
BEGIN
    Drop TABLE #tmpcheckinout
END
Create TABLE [dbo].[#tmpCheckInOut](
[MachineNo] [int] NULL,
[EnrollNo] [nvarchar](25) NULL,
[dwVMode] [int] NULL,
[dwIOMode] [int] NULL,
[dwalltime] [datetime] NULL)
ON [PRIMARY]
Create UNIQUE CLUSTERED INDEX [idx_tmpcheckio] ON [dbo].[#tmpCheckInOut] 
(
[EnrollNo] ASC,
[dwalltime] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, Drop_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]--接收数据后直接插入临时表
declare 
@intoCheck varchar(8000),
@intoCheckval varchar(7000)
set @intoCheckval=@intoCheckvalues
set @intoCheck='insert into dbo.#tmpCheckInOut (MachineNo,EnrollNo,dwVMode,dwIOMode,dwalltime) values'+@intoCheckval
EXECUTE (@intoCheck)--去重日期记录插入tblCheckInOut表
insert into dbo.tblCheckInOut (MachineNO,EnrollNo,dwVMode,dwIOMode,dwalltime)
select a.MachineNO,a.EnrollNo,a.dwVMode,a.dwIOMode,a.dwalltime
from dbo.#tmpCheckInOut a left join
dbo.tblCheckInOut b 
on a.EnrollNo=b.EnrollNo and a.dwalltime =b.dwalltime
where b.EnrollNo is null

End 推荐阅读 71ba01840dbbe080a54914c3f7e3d39f.png Access训练营  从0基础开始,循序渐进,系统化的训练营课程,整合作业、课表、社群,为学员提供答疑,获得更佳的学习效果。【详情>> 】   457e41ff7b6b05e7a5a451a9603ee3a6.png 快速开发财务管理系统  紧密结合职场的一个课程,参加培训不仅可提升开发技能,而且可获得案例源代码,立即投入到实际工作中应用。【详情>> 】   5b7c653e616d09681d4b8842f260f9c8.png Access软件作品  十二位Access学员对自已开发的软件进行了介绍并分享开发心得,一起来了解Access开发的软件。【详情>> 】   30aa157252861a93fba48674e3893a2a.png 从Excel到Access数据库  为广大Excel用户了解、学习Access数据库开设的一个实用课程,侧重于数据统计分析。【详情>> 】   fc1869e235fa79ad51cf93350485301a.png Access每天3分钟  视频课程共50集,Access的基础知识并结合示例详细讲解,每集视频只有短短几分钟,学员可以利用碎片化的时间,每天进步一点点【详情>> 】   1acea70c1170298785994288a69024c1.png 张志,Access数据库培训讲师,『Access软件网』创始人,服务过的知名企业有北京奔驰、立达(中国)纺织仪器、宜家(中国)投资等。 2003~2013年连续10年获微软最有价值专家。【详情>>】  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值