• 在C#应用程序中,利用表值参数过滤重复,批量向数据库导入数据,并且返回重复数据


      在很多情况下,应用程序都需要实现excel数据导入功能,数据如果只有几十条,或上百条,甚至上千条,速度还好。

      但是不仅如此,如果客户提供给你的excel本身存在着重复数据,或是excel中的某些数据已经在数据库存在,那这时,在向数据库插入数据前你还得判重,如果不存在才进行导入

          通常,我们第一步就会通过上传的方式把excel中的数据读到内存,然后通过循环的方式得出一条一条数据,接着对于每条数据用关键字段去往数据库中进行一次查重,若存在则不做事情,若

    不存在则向数据库中插入一条数据。这样一来,我们每一条数据都会与数据库打两次交道,众所周知,每连接一次数据库那是需要时间的,次数一多相当影响性能。若是成千上万条数据的话,可

    想而知,这个导入过程会有多慢,尤其是Web应用程序,很有可能在我的请求还没执行完,突然程序就被终止了。

           当然,还有个办法,就是拼SQL,每循环一条数据,首先判断,若不重复,我写一条SQL语句保存在某个变量中,直到循环到最后一条,可能会拼出多条Insert语句,最后送到数据库一次执

    行,但是大家有没有想过,一旦数据量过大,几万,或几十万条数据拼成的字符串可想而知会有多长,送到数据库就会有被截断的可能。更何况还是逃离不了每次都要查询重复的惨况。

      一般来说,SQL语句离数据库端越近,执行效率越高,有没有可能,我把所要插入的数据集合一次性送给数据库,让判断重复,插入,返回重复数据的工作统统由数据库来执行呢?这样我只

    要与数据库打一次交道,等待数据库给我结果就行。那么接下来就是我要讲到的利用表值参数来完成这一功能。

      由于为了讲述,例子中的表都比较简单

      1.首先我们来创建一张表(建库的过程在这里我就不说明了,为了大家看得清晰,尽量去除了无关的脚本行)

     1 CREATE TABLE [dbo].[BulkTestTable](
     2     [Id] [int] NOT NULL,
     3     [UserName] [nvarchar](32) NULL,
     4     [Pwd] [varchar](16) NULL,
     5 PRIMARY KEY CLUSTERED 
     6 (
     7     [Id] ASC
     8 )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
     9 ) ON [PRIMARY]
    10 
    11 GO

         2.创建表值类型

     1 USE [BulkTestDB]
     2 GO
     3 
     4 /****** Object:  UserDefinedTableType [dbo].[BulkTestTableType]    Script Date: 07/08/2015 16:04:38 ******/
     5 CREATE TYPE [dbo].[BulkTestTableType] AS TABLE(
     6     [Id] [int] NULL,
     7     [UserName] [nvarchar](32) NULL,
     8     [Pwd] [varchar](16) NULL
     9 )
    10 GO

        3.写批量插入的存储过程

        

    1 CREATE procedure [dbo].[usp_BulkTestTable_Import] 
    2 (@paratable as BulkTestTableType readonly) --此处的BulkTestTableType就是上面所定义的表类型,实际不用对它进行操作,只需要在程序中传入一个表给它,然后从它里面进行读取

    3 AS
    4 Insert INTO dbo.BulkTestTable(Id,UserName,Pwd) 
    5 select * from @paratable A
    6 WHERE Not EXISTS(select B.Id from BulkTestTable B WHERE B.Id=A.Id)

    7 SELECT * from @paratable A WHERE EXISTS (select B.Id from BulkTestTable B WHERE B.Id=A.Id) --查询出重复的记录
    8 GO

       在这里,我的Id不是自动增长的,仅仅是主键而已,所以这里通过Id来判断记录是否唯一或重复

      接下来在C#代码里面写一个导入方法,调用这个存储过程。

      


    这里的参数dt就是我们导入excel时生成的DataTable,这个DataTable的表结构也就是列要与我们定义的表值“
    BulkTestTableType”结构相同,返回值就是我们所要的重复记录
    1  public static DataSet BatchInsert(DataTable dt)
    2     {
    3         SqlParameter parameter = new SqlParameter("@paratable",dt);
    4         parameter.SqlDbType = SqlDbType.Structured;
    5         parameter.TypeName = "BulkTestTableType"; //这里的类型名称应与我们定义的表值名称相同

    6 SqlParameter[] sqlParameters = new SqlParameter[] { parameter };

    7return SqlHelper.RunProcedure(CommandType.StoredProcedure, "
    usp_BulkTestTable_Import", sqlParameters);
    8 }

      以上就是完整的代码,当然,怎么在内存中创建表,怎么写数据库访问方法我这里就不说明了,大家都知道。小白写文章,大家共同交流,勿喷

  • 相关阅读:
    Python字典推导式将cookie字符串转化为字典
    爬取百度贴吧前1000页内容(requests库面向对象思想实现)
    牛客网:连续子数组的最大和
    在字符串中找出第一个只出现一次的字符,Python实现
    关于时间日期的程序,主要datetime模块
    [读书笔记] Python数据分析 (五) pandas入门
    [学习笔记] CS131 Computer Vision: Foundations and Applications:Lecture 3 线性代数初步
    [读书笔记] Python数据分析 (四) 数组和矢量计算
    [读书笔记] Python数据分析 (三) IPython
    [读书笔记] R语言实战 (六) 基本图形方法
  • 原文地址:https://www.cnblogs.com/colin2011/p/4630660.html
Copyright © 2020-2023  润新知