zoukankan      html  css  js  c++  java
  • Import data from files to SQL Server(用BULK INSERT命令导入数据详解)

           本文将为大家演示如何利用BULK INSERT命令来导入数据,并讲解怎样通过改变该命令的一些选项以便更方便且更有效地插入数据。

      BULK INSERT

      在SQL Server中,BULK INSERT是用来将外部文件以一种特定的格式加载到数据库表的T-SQL命令。该命令使开发人员能够直接将数据加载到数据库表中,而不需要使用类似于Integration Services这样的外部程序。虽然BULK INSERT不允许包含任何复杂的逻辑或转换,但能够提供与格式化相关的选项,并告诉我们导入是如何实现的。BULK INSERT有一个使用限制,就是只能将数据导入SQL Server。

      插入数据下面的例子能让我们更好的理解如何使用BULK INSERT命令。首先,我们来创建一个名为Sales的表,我们将要把来自文本文件的数据插入到这个表中。

      CREATE TABLE [dbo].[Sales] 
      ( 
      [SaleID] [int], 
      [Product] [varchar](10) NULL, 
      [SaleDate] [datetime] NULL, 
      [SalePrice] [money] NULL 
      ) 

        当我们使用BULK INSERT命令来插入数据时,不要启动目标表中的触发器,因为触发器会减缓数据导入的进程。

      在下一个例子中,我们将在Sales表上创建触发器,用来打印插入到表中的记录的数量。

      CREATE TRIGGER tr_Sales 
      ON Sales 
      FOR INSERT 
      AS 
      BEGIN 
      PRINT CAST(@@ROWCOUNT AS VARCHAR(5)) + ' rows Inserted.' 
      END 

        这里我们选择文本文件作为源数据文件,文本文件中的值通过逗号分割开。该文件包含1000条记录,而且其字段和Sales表的字段直接关联。由于该文本文件中的值是由逗号分割开的,我们只需要指定FIELDTERMINATOR即可。注意,当下面这条语句运行时,我们刚刚创建的触发器并没有启动:

      BULK INSERT Sales FROM 'c:SalesText.txt' WITH (FIELDTERMINATOR = ',')

      当我们要的数据量非常大时,有时候就需要启动触发器。下面的脚本使用了FIRE_TRIGGERS选项来指明在目标表上的任何触发器都应当启动:

      BULK INSERT Sales FROM 'c:SalesText.txt' WITH (FIELDTERMINATOR = ',', FIRE_TRIGGERS)

      我们可以使用BATCHSIZE指令来设置在单个事务中可以插入到表中的记录的数量。在前一个例子中,所有的1000条记录都在同一个事务中被插入到目标表里。下面的例子,我们将BATCHSIZE参数设置为2,也就是说要对该表执行500次独立的插入事务。这也意味着启动500次触发器,所以将有 500咯打印指令输出到屏幕上。
    BULK INSERT Sales FROM 'c:SalesText.txt' WITH (FIELDTERMINATOR = ',', FIRE_TRIGGERS, BATCHSIZE = 2)

      BULK INSERT不仅仅可以应用于SQL Server 2005的本地映射驱动器。下面的语句将告诉我们如何从名为FileServer的服务器的D盘中将SalesText文件的数据导入。

      BULK INSERT Sales FROM 'FileServerD$SalesText.txt' WITH (FIELDTERMINATOR = ',')

      有时候,我们在执行导入操作以前,最好能先查看一下将要输入的数据。下面的语句在使用BULK命令时,使用了OPENROWSET函数,以便从 SalesText文本文件中读取源数据。该语句同时还需要使用一个格式文件(此处没有列出文件的具体内容)来表明该文本文件中的数据格式。

      SELECT * 
      FROM OPENROWSET(BULK 'c:SalesText.txt' , 
      FORMATFILE='C:SalesFormat.Xml' 
      ) AS mytable; 
      GO 

          


    最近做某项目的数据库分析,要实现对海量数据的导入问题,就是最多把200 万条数据一次导入sqlserver中,如果使用普通的insert语句进行写出的话,恐怕没个把小时完不成任务,先是考虑使用bcp,但这是基于命令行的,对用户来说友好性太差,实际不大可能使用;最后决定使用BULK INSERT语句实现,BULK INSERT也可以实现大数据量的导入,而且可以通过编程实现,界面可以做的非常友好,它的速度也很高:导入100万条数据不到20秒中,在速度上恐怕无出其右者。
    但是使用这种方式也有它的几个缺点:
    1.需要独占接受数据的表
    2.会产生大量的日志
    3.从中取数据的文件有格式限制
    但相对于它的速度来说,这些缺点都是可以克服的,而且你如果愿意牺牲一点速度的话,还可以做更精确的控制,甚至可以控制每一行的插入。
    对与产生占用大量空间的日志的情况,我们可以采取在导入前动态更改数据库的日志方式为大容量日志记录恢复模式,这样就不会记录日志了,导入结束后再恢复原来的数据库日志记录方式。
    具体的一个语句我们可以这样写:

    代码如下:

    alter database taxi
    set RECOVERY BULK_LOGGED
    BULK INSERT taxi..detail FROM 'e:\out.txt'
    WITH (
    DATAFILETYPE = 'char',
    FIELDTERMINATOR = ',',
    ROWTERMINATOR = '\n',
    TABLOCK
    )
    alter database taxi
    set RECOVERY FULL


    这个语句将从e:\out.txt导出数据文件到数据库taxi的detail表中。

     

    from: http://www.cnblogs.com/andy_tigger/archive/2009/10/15/1584076.html

  • 相关阅读:
    Linux基本知识
    Linux 基金会发起开源创新计划,为全球对抗 COVID-19 提供基础架构
    单片机程序设计有十层功力,你现在在哪一层?
    C语言太复杂?CUDA Python也能实现并行计算加速!
    Java 基础 子类赋值给父类问题
    SpringBlade AVUE 拖拽排序
    java 基础 Long类型 判断是否相等
    数字量输入模块和模拟量输入模块的区别是什么?
    模拟量输入模块和模拟量输出模块的应用范围
    NB-IOT关键技术分析
  • 原文地址:https://www.cnblogs.com/Langzi127/p/1783556.html
Copyright © 2011-2022 走看看