BULK INSERT (Transact-SQL)

适用于:SQL ServerAzure SQL 数据库Azure SQL 托管实例

在 SQL Server 中以用户指定的格式将数据文件导入到数据库表或视图中

Transact-SQL 语法约定

语法

BULK INSERT
   { database_name.schema_name.table_or_view_name | schema_name.table_or_view_name | table_or_view_name }
      FROM 'data_file'
     [ WITH
    (
   [ [ , ] BATCHSIZE = batch_size ]
   [ [ , ] CHECK_CONSTRAINTS ]
   [ [ , ] CODEPAGE = { 'ACP' | 'OEM' | 'RAW' | 'code_page' } ]
   [ [ , ] DATAFILETYPE =
      { 'char' | 'native' | 'widechar' | 'widenative' } ]
   [ [ , ] DATA_SOURCE = 'data_source_name' ]
   [ [ , ] ERRORFILE = 'file_name' ]
   [ [ , ] ERRORFILE_DATA_SOURCE = 'errorfile_data_source_name' ]
   [ [ , ] FIRSTROW = first_row ]
   [ [ , ] FIRE_TRIGGERS ]
   [ [ , ] FORMATFILE_DATA_SOURCE = 'data_source_name' ]
   [ [ , ] KEEPIDENTITY ]
   [ [ , ] KEEPNULLS ]
   [ [ , ] KILOBYTES_PER_BATCH = kilobytes_per_batch ]
   [ [ , ] LASTROW = last_row ]
   [ [ , ] MAXERRORS = max_errors ]
   [ [ , ] ORDER ( { column [ ASC | DESC ] } [ ,...n ] ) ]
   [ [ , ] ROWS_PER_BATCH = rows_per_batch ]
   [ [ , ] ROWTERMINATOR = 'row_terminator' ]
   [ [ , ] TABLOCK ]

   -- input file format options
   [ [ , ] FORMAT = 'CSV' ]
   [ [ , ] FIELDQUOTE = 'quote_characters']
   [ [ , ] FORMATFILE = 'format_file_path' ]
   [ [ , ] FIELDTERMINATOR = 'field_terminator' ]
   [ [ , ] ROWTERMINATOR = 'row_terminator' ]
    )]

注意

若要查看 SQL Server 2014 (12.x) 及更早版本的 Transact-SQL 语法,请参阅早期版本文档

参数

database_name

指定的表或视图所在的数据库的名称。 如果未指定,则 database_name 是当前数据库。

schema_name

指定表或视图架构的名称。 如果用户执行批量导入操作的默认架构为指定表或视图的架构,则 schema_name 是可选的。 如果未指定架构且用户执行批量导入操作的默认架构不是指定表或视图的架构,则 SQL Server 会返回一条错误消息,同时取消批量导入操作。

table_name

指定要将数据批量导入其中的表或视图的名称。 只能使用所有列均引用相同基表的视图。 有关将数据加载到视图中的限制的详细信息,请参阅 INSERT (Transact-SQL)

FROM 'data_file'

指定数据文件的完整路径,该数据文件包含要导入到指定表或视图中的数据。 使用 BULK INSERT 可以从磁盘或 Azure Blob 存储(包括网络、软盘、硬盘等)导入数据。

data_file 必须基于运行 SQL Server 的服务器指定一个有效路径。 如果 data_file 为远程文件,则指定通用命名约定 (UNC) 名称。 UNC 名称采用 \\SystemName\ShareName\Path\FileName 格式。 例如:

BULK INSERT Sales.Orders
FROM '\\SystemX\DiskZ\Sales\data\orders.dat';

从 SQL Server 2017 (14.x) 开始,data_file 可位于 Azure Blob 存储中。 在这种情况下,需要指定 data_source_name 选项。 有关示例,请参阅从 Azure Blob 存储中的文件导入数据

Azure SQL 数据库仅支持从 Azure blob 存储读取内容。

BATCHSIZE = batch_size

指定批处理中的行数。 每个批处理作为一个事务复制到服务器。 如果复制操作失败,则 SQL Server 将提交或回滚每个批处理的事务。 默认情况下,指定数据文件中的所有数据为一个批处理。 有关性能注意事项的信息,请参阅本文后面的性能注意事项

CHECK_CONSTRAINTS

指定在批量导入操作期间,必须检查所有对目标表或视图的约束。 若没有 CHECK_CONSTRAINTS 选项,则忽略所有 CHECK 和 FOREIGN KEY 约束,并在该操作后将表的约束标记为不可信。

始终强制使用 UNIQUE 和 PRIMARY KEY 约束。 导入使用 NOT NULL 约束定义的字符列时,当文本文件中没有值时,BULK INSERT 插入一个空白字符串。

有时必须检查针对整个表的约束。 执行大容量导入操作之前,如果表不为空,则重新验证约束的代价可能会超出对增量数据应用 CHECK 约束的代价。

当输入数据包含违反约束的行时,您可能希望禁用约束(默认行为)。 禁用 CHECK 约束后,你可以导入数据并使用 Transact-SQL 语句删除无效数据。

备注

MAXERRORS 选项不适用于约束检查。

CODEPAGE = { 'ACP' | 'OEM' | 'RAW' | 'code_page' }

指定该数据文件中数据的代码页。 仅当数据含有字符值大于 127 或小于 32charvarchartext 列时,CODEPAGE 才适用。 有关示例,请参阅指定代码页

Linux for SQL Server 2017 (14.x) 不支持 CODEPAGE 选项。 对于 SQL Server 2019 (15.x),只能对 CODEPAGE 使用“RAW”选项。

应在格式文件中为每个列指定一个排序规则名称。

CODEPAGE 值 说明
ACP 数据类型为 charvarchartext 的列从 ANSI/Microsoft Windows 代码页 (ISO 1252) 转换为 SQL Server 代码页。
OEM(默认值) 数据类型为 charvarchartext 的列从系统 OEM 代码页转换为 SQL Server 代码页。
RAW 不进行代码页间的转换。 RAW 是速度最快的选项。
code_page 特定的代码页码,例如 850。

低于 SQL Server 2016 (13.x) 的版本不支持代码页 65001(UTF-8 编码)。

DATAFILETYPE = { 'char' | 'native' | 'widechar' | 'widenative' }

指定 BULK INSERT 使用指定的数据文件类型值执行导入操作。

DATAFILETYPE 值 所有数据都表示为:
char(默认值) 字符格式。

有关详细信息,请参阅使用字符格式导入或导出数据 (SQL Server)
native 本机(数据库)数据类型。 通过使用 bcp 实用工具从 SQL Server 批量导入数据来创建本机数据文件。

与 char 值相比,本机值提供更高的性能。 使用不包含任何扩展/双字节字符集 (DBCS) 字符的数据文件在多个 SQL Server 实例之间批量传输数据时,建议使用本机格式。

有关详细信息,请参阅使用本机格式导入或导出数据 (SQL Server)
widechar Unicode 字符。

有关详细信息,请参阅使用 Unicode 字符格式导入或导出数据 (SQL Server)
widenative 本机(数据库)数据类型,charvarchartext 列除外,这些列中的数据均以 Unicode 格式存储。 通过使用 bcp 实用工具从 SQL Server 批量导入数据来创建 widenative 数据文件。

widechar 相比,widenative 值可以提供更高的性能。 如果数据文件包含 ANSI 扩展字符,则指定 widenative

有关详细信息信息,请参阅使用 Unicode 本机格式导入或导出数据 (SQL Server)

DATA_SOURCE = 'data_source_name'

适用于:SQL Server 2017 (14.x) 和 Azure SQL 数据库。

指定命名的外部数据源,指向将导入文件的 Azure Blob 存储位置。 外部数据源必须使用 SQL Server 2017 (14.x) 中添加的 TYPE = BLOB_STORAGE 选项创建。 有关详细信息,请参阅 CREATE EXTERNAL DATA SOURCE。 有关示例,请参阅从 Azure Blob 存储中的文件导入数据

ERRORFILE = 'error_file_path'

指定用于收集格式有误且不能转换为 OLE DB 行集的行的文件。 这些行将按原样从数据文件复制到此错误文件中。

错误文件是执行命令时创建的。 如果该文件已经存在,则会发生错误。 此外,将创建扩展名为 .ERROR.txt 的控制文件,该文件引用错误文件中的每一行并提供错误诊断。 纠正错误后即可加载数据。

从 SQL Server 2017 (14.x) 开始,error_file_path 可位于 Azure Blob 存储中。

ERRORFILE_DATA_SOURCE = 'errorfile_data_source_name'

适用对象:SQL Server 2017 (14.x)。

指定命名的外部数据源,指向错误文件的 Azure Blob 存储位置,该错误文件包含导入过程中发现的错误。 外部数据源必须使用 SQL Server 2017 (14.x) 中添加的 TYPE = BLOB_STORAGE 选项创建。 有关详细信息,请参阅 CREATE EXTERNAL DATA SOURCE

FIRSTROW = first_row

指定要加载的第一行的行号。 默认值是指定数据文件中的第一行。 FIRSTROW 从 1 开始。

FIRSTROW 属性不可用于跳过列标题。 BULK INSERT 语句不支持跳过标题。 如果你选择跳过行,SQL Server 数据库引擎只考虑字段终止符,而不会对所跳过行的字段中的数据进行验证。

FIRE_TRIGGERS

指定将在大容量导入操作期间执行目标表中定义的所有插入触发器。 如果为针对目标表的 INSERT 操作定义了触发器,则每次完成批处理操作时均激发触发器。

如果未指定 FIRE_TRIGGERS,则不执行任何插入触发器操作。

FORMATFILE_DATA_SOURCE = 'data_source_name'

适用对象:SQL Server 2017 (14.x)。

指定命名的外部数据源,指向格式化文件(定义导入数据的架构)的 Azure Blob 存储位置。 外部数据源必须使用 SQL Server 2017 (14.x) 中添加的 TYPE = BLOB_STORAGE 选项创建。 有关详细信息,请参阅 CREATE EXTERNAL DATA SOURCE

KEEPIDENTITY

指定导入数据文件中的标识值用于标识列。 如果没有指定 KEEPIDENTITY,则此列的标识值可被验证但不能导入,并且 SQL Server 将根据创建表的过程中指定的种子值和增量值自动分配唯一值。 如果数据文件不包含该表或视图中标识列的值,请使用格式化文件指定在导入数据时跳过表或视图中的标识列;SQL Server 会自动为该列分配唯一的值。 有关详细信息,请参阅 DBCC CHECKIDENT (Transact-SQL)

有关如何保留标识值的详细信息,请参阅批量导入数据时保留标识值 (SQL Server)

KEEPNULLS

指定空列在大容量导入操作期间应保留 Null 值,而不插入列的任何默认值。 有关详细信息,请参阅在批量导入期间保留 Null 或使用默认值 (SQL Server)

KILOBYTES_PER_BATCH = kilobytes_per_batch

将每个批处理中数据的近似千字节数 (KB) 指定为 kilobytes_per_batch。 默认情况下,KILOBYTES_PER_BATCH 是未知的。 有关性能注意事项的信息,请参阅本文后面的性能注意事项

LASTROW = last_row

指定要加载的最后一行的行号。 默认值为 0,表示指定数据文件中的最后一行。

MAXERRORS = max_errors

指定允许在数据中出现的最大语法错误数,超过该数量后将取消大容量导入操作。 批量导入操作无法导入的每一行都将被忽略并且计为一个错误。 如果未指定 max_errors,则默认值为 10。

MAX_ERRORS 选项不适用于约束检查,也不适用于转换 money 和 bigint 数据类型。

ORDER ( { column [ ASC | DESC ] } [ ,... n ] )

指定如何对数据文件中的数据排序。 如果根据表中的聚集索引(如果有)对要导入的数据排序,则可提高批量导入的性能。 如果数据文件按不同于聚集索引键的顺序排序,或者该表没有聚集索引,则忽略 ORDER 子句。 提供的列名必须是目标表中有效的列名。 默认情况下,大容量插入操作假设数据文件未排序。 对于经过优化的批量导入, SQL Server 还将验证导入的数据是否已排序。

n 是指示可以指定多个列的占位符。

ROWS_PER_BATCH = rows_per_batch

指示数据文件中近似的数据行数量。

默认情况下,数据文件中所有的数据都作为单一事务发送到服务器,批处理中的行数对于查询优化器是未知的。 如果指定了 ROWS_PER_BATCH(值 > 0),则服务器将使用此值优化批量导入操作。 为 ROWS_PER_BATCH 指定的值应当与实际行数大致相同。 有关性能注意事项的信息,请参阅本文后面的性能注意事项

TABLOCK

指定在大容量导入操作持续时间内获取一个表级锁。 如果表没有索引并且指定了 TABLOCK,则该表可以同时由多个客户端加载。 默认情况下,锁定行为由表选项 table lock on bulk load决定。 通过在大容量导入操作期间保留锁,可减少对表争用锁的情况,有时可显著提高性能。 有关性能注意事项的信息,请参阅本文后面的性能注意事项

对于列存储索引,锁定行为有所不同,因为它在内部划分为多个行集。 每个线程通过在行集上使用 X 锁,允许使用并发数据加载会话并行加载数据,从而将数据以独占方式加载到每个行集中。 使用 TABLOCK 选项会导致线程在表上使用 X 锁(与传统行集的 BU 锁不同),这会阻止其他并发线程并发加载数据。

输入文件格式选项

FORMAT = 'CSV'

适用对象:SQL Server 2017 (14.x)。

指定符合 RFC 4180 标准的逗号分隔值文件。

BULK INSERT Sales.Orders
FROM '\\SystemX\DiskZ\Sales\data\orders.csv'
WITH ( FORMAT = 'CSV');

FIELDQUOTE = 'field_quote'

适用对象:SQL Server 2017 (14.x)。

指定将用作 CSV 文件引号字符的字符。 如果未指定,根据 RFC 4180 标准中的定义,引号字符 (") 将用作引号字符。

FORMATFILE = 'format_file_path'

指定格式化文件的完整路径。 描述数据文件的格式化文件,数据文件中包含存储的响应,而存储的响应则是使用 bcp 实用工具在同一表或视图中创建的。 在下列情况下应使用格式化文件:

  • 数据文件包含的列多于或少于表或视图包含的列。
  • 列的顺序不同。
  • 列分隔符不同。
  • 数据格式有其他更改。 格式化文件通常使用 bcp 实用工具创建,并可根据需要使用文本编辑器修改。 有关详细信息,请参阅 bcp 实用工具创建格式化文件

从 2017 SQL Server 2017 (14.x) 开始,在 Azure SQL 数据库中,format_file_path 可以位于 Azure Blob 存储中。

FIELDTERMINATOR = 'field_terminator'

指定要用于 charwidechar 数据文件的字段终止符。 默认字段终止符为 \t(制表符)。 有关详细信息,请参阅指定字段终止符和行终止符 (SQL Server)

ROWTERMINATOR = 'row_terminator'

指定要用于 charwidechar 数据文件的行终止符。 默认行终止符为 \r\n(换行符)。 有关详细信息,请参阅指定字段终止符和行终止符 (SQL Server)

兼容性

BULK INSERT 将对从文件中读取的数据执行严格的数据验证和数据检查,在对无效数据执行这样的验证和检查时,可能导致现有脚本失败。 例如,BULK INSERT 验证:

  • floatreal 数据类型的本机表示形式是否有效。
  • Unicode 数据的字节数是否为偶数。

数据类型

字符串到小数的数据类型转换

BULK INSERT 中使用的字符串到小数的数据类型转换与 Transact-SQL CONVERT 函数遵循相同的规则,该函数拒绝使用科学记数法表示数值的字符串。 因此,BULK INSERT 将此类字符串视为无效值并报告转换错误。

若要绕过此行为,可使用格式化文件将以科学记数法表示的 float 数据批量导入小数列中。 在格式化文件中,请将列显式描述为 realfloat 数据。 有关这些数据类型的详细信息,请参阅 float 和 real (Transact-SQL)

格式化文件将 real 数据表示为 SQLFLT4 数据类型,将 float 数据表示为 SQLFLT8 数据类型。 有关非 XML 格式化文件的详细信息,请参阅使用 bcp 指定文件存储类型 (SQL Server)

导入使用科学记数法的数值的示例

该示例使用 bulktest 数据库中的以下表:

CREATE TABLE dbo.t_float(c1 FLOAT, c2 DECIMAL (5,4));

用户要将数据大容量导入 t_float 表中。 数据文件 C:\t_float-c.dat 包含以科学记数法表示的 float 数据,例如:

8.0000000000000002E-2 8.0000000000000002E-2

复制此示例时,请注意将制表符 (\t) 保存为空格的不同文本编辑器和编码。 此示例稍后会出现制表符。

但是,BULK INSERT 无法将此数据直接导入 t_float,原因是其第二个列 c2 使用的是 decimal 数据类型。 因此,必须使用格式化文件。 格式化文件必须将以科学记数法表示的 float 数据映射到列 c2 的小数格式。

以下格式化文件使用 SQLFLT8 数据类型将第二个数据字段映射到第二列:

<?xml version="1.0"?>
<BCPFORMAT xmlns="http://schemas.microsoft.com/sqlserver/2004/bulkload/format" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<RECORD>
<FIELD ID="1" xsi:type="CharTerm" TERMINATOR="\t" MAX_LENGTH="30"/>
<FIELD ID="2" xsi:type="CharTerm" TERMINATOR="\r\n" MAX_LENGTH="30"/> </RECORD> <ROW>
<COLUMN SOURCE="1" NAME="c1" xsi:type="SQLFLT8"/>
<COLUMN SOURCE="2" NAME="c2" xsi:type="SQLFLT8"/> </ROW> </BCPFORMAT>

若要使用此格式化文件(使用文件名 C:\t_floatformat-c-xml.xml)将测试数据导入测试表中,请发出下列 Transact-SQL 语句:

BULK INSERT bulktest.dbo.t_float
FROM 'C:\t_float-c.dat' WITH (FORMATFILE = 'C:\t_floatformat-c-xml.xml');

重要

Azure SQL 数据库 仅支持从 Azure blob 存储读取内容。

用于批量导出或导入 SQLXML 文档的数据类型

若要大容量导出或导入 SQLXML 数据,请在格式化文件中使用下列数据类型之一:

数据类型 效果
SQLCHAR 或 SQLVARCHAR 在客户端代码页或排序规则隐含的代码页中发送数据。 效果与指定 DATAFILETYPE = 'char' 而不指定格式化文件相同。
SQLNCHAR 或 SQLNVARCHAR 以 Unicode 格式发送数据。 效果与指定 DATAFILETYPE = 'widechar' 而不指定格式化文件相同。
SQLBINARY 或 SQLVARBIN 不经任何转换即发送数据。

备注

有关 BULK INSERT 语句、INSERT ... SELECT * FROM OPENROWSET(BULK...) 语句和 bcp 命令,请参阅批量导入和导出数据 (SQL Server)

有关准备数据以进行批量导入的信息,请参阅准备用于批量导出或导入的数据 (SQL Server)

BULK INSERT 语句可在用户定义的事务内执行,以便将数据导入到表或视图中。 或者,为了将多个匹配项用于大容量导入数据,事务可以在 BULK INSERT 语句中指定 BATCHSIZE 子句。 如果回滚某一多批处理事务,则回滚该事务已发送到 SQL Server 的每个批处理。

互操作性

从 CSV 文件导入数据

从 SQL Server 2017 (14.x) 开始,BULK INSERT 与 Azure SQL 数据库一样都支持 CSV 格式。

在 SQL Server 2017 (14.x) 之前,SQL Server 批量导入操作不支持逗号分隔值 (CSV) 文件。 但是,在某些情况下,CSV 文件可在将数据大容量导入 SQL Server时用作数据文件。 有关从 CSV 数据文件导入数据的要求,请参阅准备用于批量导出或导入的数据 (SQL Server)

日志行为

有关何时在事务日志中记录由批量导入 SQL Server 执行的行插入操作的信息,请参阅批量导入的最小日志记录的先决条件。 Azure SQL 数据库中不支持最小日志记录。

限制

将格式文件用于 BULK INSERT 时,最多只能指定 1024 个字段。 这与表中允许的最大列数相同。 如果将带 BULK INSERT 的格式化文件与包含 1024 个字段以上的数据文件一起使用,BULK INSERT 将生成 4822 错误。 bcp 实用工具没有此限制,因此,对于包含 1024 个以上字段的数据文件,请使用不带格式化文件 BULK INSERT 或使用 bcp 命令。

性能注意事项

如果要在单次批处理中刷新的页数超过了内部阈值,则可能会对缓冲池执行完全扫描,以识别要在批处理提交时刷新的页面。 此完全扫描可能会降低大容量导入操作的性能。 在将大型缓冲池与较慢的 I/O 子系统结合使用时,就可能出现超过内部阈值的情况。 若要避免大型机上的缓冲区溢出,请不要使用 TABLOCK 提示(将删除批量优化),也不要使用较小的批大小(将保留批量优化)。

应在数据加载过程中测试各种批大小,以确定最佳方案。 请记住,批大小会影响部分回滚。 如果过程失败,在再次使用 BULK INSERT 之前,可能需要执行其他手动操作以删除发生失败之前成功插入的一部分行。

使用 Azure SQL 数据库,如果要导入大量数据,请考虑在导入之前暂时提高数据库或实例的性能级别。

安全性

安全帐户委托(模拟)

如果用户使用的是 SQL Server 登录名,则系统将使用 SQL Server 进程帐户的安全配置文件。 使用 SQL Server 身份验证的登录名不能在数据库引擎外部进行身份验证。 因此,当 BULK INSERT 命令由使用 SQL Server 身份验证的登录名启动时,使用 SQL Server 进程帐户(SQL Server 数据库引擎服务使用的帐户)的安全上下文建立到数据的连接。

要成功读取源数据,您必须授予 SQL Server 数据库引擎使用的帐户访问源数据的权限。 与此相反,如果 SQL Server 用户使用 Windows 身份验证登录,则该用户只能读取用户帐户可以访问的那些文件,而不考虑 SQL Server 进程的安全配置文件。

如果在一台计算机上使用 sqlcmdosql 执行 BULK INSERT 语句,将数据插入第二台计算机上的 SQL Server,同时使用 UNC 路径在第三台计算机上指定 data_file,可能会收到 4861 错误。

若要解决此问题,请使用 SQL Server 身份验证并指定一个使用 SQL Server 进程帐户安全配置文件的 SQL Server 登录名,或者配置 Windows 以启用安全帐户委托。 有关如何使用户帐户可信以进行委托的信息,请参阅 Windows 帮助。

有关详细信息和使用 BULK INSERT 的安全注意事项,请参阅使用 BULK INSERT 或 OPENROWSET(BULK...) 导入批量数据 (SQL Server)

从 Azure Blob 存储导入数据且数据非公共数据(匿名访问)时,请基于使用 MASTER KEY 加密的 SAS 密钥创建一个 DATABASE SCOPED CREDENTIAL,然后创建一个外部数据库源以用于 BULK INSERT 命令。

或者,基于 MANAGED IDENTITY 创建 DATABASE SCOPED CREDENTIAL,以对有关访问非公共存储帐户中的数据的请求授权。 使用 MANAGED IDENTITY 时,Azure 存储必须通过添加“存储 Blob 数据参与者”内置 Azure 基于角色的访问控制 (RBAC) 角色来授予对实例的托管标识的权限,该角色为必要的Azure Blob 存储容器提供对托管标识的读/写访问权限。 Azure SQL 托管实例具有系统分配的托管标识,还可以具有一个或多个用户分配的托管标识。 可以使用系统分配的托管标识或用户分配的托管标识来授权请求。 对于授权,将使用托管实例的 default 标识(即主要用户分配的托管标识,如果未指定用户分配的托管标识,则为系统分配的托管标识)。 有关示例,请参阅从 Azure Blob 存储中的文件导入数据

重要

托管标识仅适用于 Azure SQL。 SQL Server 不支持托管标识。

权限

需要 INSERT 和 ADMINISTER BULK OPERATIONS 权限。 在 Azure SQL 数据库中,需要 INSERT 和 ADMINISTER DATABASE BULK OPERATIONS 权限。 Linux 上的 SQL Server 不支持 ADMINISTER BULK OPERATIONS 权限或 bulkadmin 角色。 只有 sysadmin 才能对 Linux 上的 SQL Server 执行批量插入。

另外,如果满足以下一个或多个条件,则还需要 ALTER TABLE 权限:

  • 存在约束但未指定 CHECK_CONSTRAINTS 选项。

    禁用约束是默认行为。 若要显式检查约束,请使用 CHECK_CONSTRAINTS 选项。

  • 存在触发器但未指定 FIRE_TRIGGER 选项。

    默认情况下,不会激发触发器。 若要显式激发触发器,请使用 FIRE_TRIGGER 选项。

  • 使用 KEEPIDENTITY 选项可以从数据文件中导入标识值。

示例

A. 使用竖线从文件导入数据

下面的示例使用竖线 (AdventureWorks2022.Sales.SalesOrderDetail) 作为字段终止符,并使用 | 作为行终止符,将订单详细信息从指定的数据文件导入 |\n 表中。

BULK INSERT AdventureWorks2022.Sales.SalesOrderDetail
   FROM 'f:\orders\lineitem.tbl'
   WITH
      (
         FIELDTERMINATOR = ' |'
         , ROWTERMINATOR = ' |\n'
      );

重要

Azure SQL 数据库仅支持从 Azure blob 存储读取内容。

B. 使用 FIRE_TRIGGERS 参数

下面的示例指定 FIRE_TRIGGERS 参数。

BULK INSERT AdventureWorks2022.Sales.SalesOrderDetail
   FROM 'f:\orders\lineitem.tbl'
   WITH
     (
         FIELDTERMINATOR = ' |'
         , ROWTERMINATOR = ':\n'
         , FIRE_TRIGGERS
      );

重要

Azure SQL 数据库仅支持从 Azure blob 存储读取内容。

C. 使用换行符作为行终止符

下面的示例将导入使用换行符作为行终止符的文件(如 UNIX 输出):

DECLARE @bulk_cmd VARCHAR(1000);
SET @bulk_cmd = 'BULK INSERT AdventureWorks2022.Sales.SalesOrderDetail
FROM ''<drive>:\<path>\<filename>''
WITH (ROWTERMINATOR = '''+CHAR(10)+''')';
EXEC(@bulk_cmd);

注意

由于 Microsoft Windows 处理文本文件的方式,\n 将自动替换为 \r\n

重要

Azure SQL 数据库 仅支持从 Azure blob 存储读取内容。

D. 指定一个代码页

以下示例显示如何指定代码页。

BULK INSERT MyTable
FROM 'D:\data.csv'
WITH
( CODEPAGE = '65001'
   , DATAFILETYPE = 'char'
   , FIELDTERMINATOR = ','
);

重要

Azure SQL 数据库仅支持从 Azure blob 存储读取内容。

E. 从 CSV 文件导入数据

下面的示例演示如何指定 CSV 文件:跳过标头(第一行),使用 ; 作为字段终止符,使用 0x0a 作为行终止符:

BULK INSERT Sales.Invoices
FROM '\\share\invoices\inv-2016-07-25.csv'
WITH (FORMAT = 'CSV'
      , FIRSTROW = 2
      , FIELDQUOTE = '\'
      , FIELDTERMINATOR = ';'
      , ROWTERMINATOR = '0x0a');

以下示例演示如何指定 UTF-8 格式的 CSV 文件(使用 65001CODEPAGE),跳过标头(第一行),使用 ; 作为字段终止符,使用 0x0a 作为行终止符:

BULK INSERT Sales.Invoices
FROM '\\share\invoices\inv-2016-07-25.csv'
WITH ( CODEPAGE = '65001'
      , FORMAT = 'CSV'
      , FIRSTROW = 2
      , FIELDQUOTE = '\'
      , FIELDTERMINATOR = ';'
      , ROWTERMINATOR = '0x0a');

重要

Azure SQL 数据库仅支持从 Azure blob 存储读取内容。

F. 从 Azure Blob 存储中的文件导入数据

以下示例演示如何从已创建共享访问签名 (SAS) 的 Azure Blob 存储位置中的 CSV 文件加载数据。 Azure Blob 存储位置配置为外部数据源,该数据源需要一个使用 SAS 密钥的、通过用户数据库中的主密钥加密的数据库范围凭据。

--> Optional - a MASTER KEY is not required if a DATABASE SCOPED CREDENTIAL is not required because the blob is configured for public (anonymous) access!
CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'YourStrongPassword1';
GO
--> Optional - a DATABASE SCOPED CREDENTIAL is not required because the blob is configured for public (anonymous) access!
CREATE DATABASE SCOPED CREDENTIAL MyAzureBlobStorageCredential
WITH IDENTITY = 'SHARED ACCESS SIGNATURE',
SECRET = '******srt=sco&sp=rwac&se=2017-02-01T00:55:34Z&st=2016-12-29T16:55:34Z***************';

-- NOTE: Make sure that you don't have a leading ? in SAS token, and
-- that you have at least read permission on the object that should be loaded srt=o&sp=r, and
-- that expiration period is valid (all dates are in UTC time)

CREATE EXTERNAL DATA SOURCE MyAzureBlobStorage
WITH ( TYPE = BLOB_STORAGE,
          LOCATION = 'https://****************.blob.core.windows.net/invoices'
          , CREDENTIAL = MyAzureBlobStorageCredential --> CREDENTIAL is not required if a blob is configured for public (anonymous) access!
);

BULK INSERT Sales.Invoices
FROM 'inv-2017-12-08.csv'
WITH (DATA_SOURCE = 'MyAzureBlobStorage');

下面的示例演示如何使用 BULK INSERT 命令通过托管标识从 Azure Blob 存储位置中的 csv 文件加载数据。 Azure Blob 存储位置配置为外部数据源。

--> Optional - a MASTER KEY is not required if a DATABASE SCOPED CREDENTIAL is not required because the blob is configured for public (anonymous) access!
CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'YourStrongPassword1';
GO
--> Optional - a DATABASE SCOPED CREDENTIAL is not required because the blob is configured for public (anonymous) access!
CREATE DATABASE SCOPED CREDENTIAL MyAzureBlobStorageCredential 
WITH IDENTITY = 'Managed Identity';
-- NOTE: Make sure you have granted Storage Bob Data Contributor RBAC on storage to provides read/write access to the managed identity for the necessary Azure Blob Storage containers.
CREATE EXTERNAL DATA SOURCE MyAzureBlobStorage
WITH ( TYPE = BLOB_STORAGE,
          LOCATION = 'https://****************.blob.core.windows.net/invoices'
          , CREDENTIAL= MyAzureBlobStorageCredential --> CREDENTIAL is not required if a blob is configured for public (anonymous) access!
);
BULK INSERT Sales.Invoices
FROM 'inv-2017-12-08.csv'
WITH (DATA_SOURCE = 'MyAzureBlobStorage');

重要

托管标识仅适用于 Azure SQL。 SQL Server 不支持托管标识。

重要

Azure SQL 仅支持从 Azure Blob 存储读取内容。

G. 从 Azure Blob 存储中的文件导入数据并指定错误文件

以下示例显示如何从 Azure Blob 存储位置(已配置为外部数据源且指定错误文件)中的 CSV 文件加载数据。 需要提供使用共享访问签名的数据库范围凭据。 如果在 Azure SQL 数据库上运行,则 ERRORFILE 选项应带有 ERRORFILE_DATA_SOURCE,否则导入可能会失败,出现权限错误。 ERRORFILE 中指定的文件不应存在于容器中。

BULK INSERT Sales.Invoices
FROM 'inv-2017-12-08.csv'
WITH (
         DATA_SOURCE = 'MyAzureInvoices'
         , FORMAT = 'CSV'
         , ERRORFILE = 'MyErrorFile'
         , ERRORFILE_DATA_SOURCE = 'MyAzureInvoices');

有关完整的 BULK INSERT 示例(包括配置凭据和外部数据源),请参阅有关批量访问 Azure Blob 存储中数据的示例

更多示例

以下文章提供了其他 BULK INSERT 示例:

另请参阅