批量插入 (Transact-SQL)

适用于:SQL ServerAzure SQL 数据库Azure SQL 托管实例Microsoft Fabric 中的仓库

在 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
    (
   [ [ , ] DATA_SOURCE = 'data_source_name' ]

   -- text formatting options
   [ [ , ] CODEPAGE = { 'RAW' | 'code_page' | 'ACP' | 'OEM' } ]
   [ [ , ] DATAFILETYPE = { 'char' | 'widechar' | 'native' | 'widenative' } ]
   [ [ , ] ROWTERMINATOR = 'row_terminator' ]
   [ [ , ] FIELDTERMINATOR = 'field_terminator' ]
   [ [ , ] FORMAT = 'CSV' ]
   [ [ , ] FIELDQUOTE = 'quote_characters' ]
   [ [ , ] FIRSTROW = first_row ]
   [ [ , ] LASTROW = last_row ]

   -- input file format options
   [ [ , ] FORMATFILE = 'format_file_path' ]
   [ [ , ] FORMATFILE_DATA_SOURCE = 'data_source_name' ]

   -- error handling options
   [ [ , ] MAXERRORS = max_errors ]
   [ [ , ] ERRORFILE = 'file_name' ]
   [ [ , ] ERRORFILE_DATA_SOURCE = 'errorfile_data_source_name' ]

   -- database options
   [ [ , ] KEEPIDENTITY ]
   [ [ , ] KEEPNULLS ]
   [ [ , ] FIRE_TRIGGERS ]
   [ [ , ] CHECK_CONSTRAINTS ]
   [ [ , ] TABLOCK ]

   -- source options
   [ [ , ] ORDER ( { column [ ASC | DESC ] } [ , ...n ] ) ]
   [ [ , ] ROWS_PER_BATCH = rows_per_batch ]
   [ [ , ] KILOBYTES_PER_BATCH = kilobytes_per_batch ]
   [ [ , ] BATCHSIZE = batch_size ]

    ) ]
BULK INSERT
   { database_name.schema_name.table_or_view_name | schema_name.table_or_view_name | table_or_view_name }
      FROM 'data_file'
     [ WITH
    (
   [ [ , ] DATA_SOURCE = 'data_source_name' ]

   -- text formatting options
   [ [ , ] CODEPAGE = { 'code_page' | 'ACP' } ]
   [ [ , ] DATAFILETYPE = { 'char' | 'widechar' } ]
   [ [ , ] ROWTERMINATOR = 'row_terminator' ]
   [ [ , ] FIELDTERMINATOR = 'field_terminator' ]
   [ [ , ] FORMAT = { 'CSV' | 'PARQUET' } ]
   [ [ , ] FIELDQUOTE = 'quote_characters' ]
   [ [ , ] FIRSTROW = first_row ]
   [ [ , ] LASTROW = last_row ]

   -- input file format options
   [ [ , ] FORMATFILE = 'format_file_path' ]
   [ [ , ] FORMATFILE_DATA_SOURCE = 'data_source_name' ]

   -- error handling options
   [ [ , ] MAXERRORS = max_errors ]
   [ [ , ] ERRORFILE = 'file_name' ]
   [ [ , ] ERRORFILE_DATA_SOURCE = 'errorfile_data_source_name' ]

    ) ]

参数

BULK INSERT 语句在不同平台上具有不同的参数和选项。 下表汇总了差异:

特征 SQL Server Azure SQL 数据库和 Azure SQL 托管实例 Fabric 数据仓库
数据源 本地路径、网络路径(UNC)或 Azure 存储 Azure 存储 Azure Storage,一湖
源身份验证 Windows 身份验证、SAS Microsoft Entra ID、SAS 令牌、托管标识 Microsoft Entra ID
不支持的选项 * 路径中的万能牌, FORMAT = 'PARQUET' * 路径中的万能牌, FORMAT = 'PARQUET' DATAFILETYPE = {'native' | 'widenative'}
已启用选项,但不起作用 KEEPIDENTITYFIRE_TRIGGERS, , CHECK_CONSTRAINTSTABLOCKORDERROWS_PER_BATCHKILOBYTES_PER_BATCHBATCHSIZE适用。 它们不会抛出语法错误,但也没有任何影响

database_name

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

schema_name

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

table_name

指定要将数据批量导入其中的表或视图的名称。 只能使用所有列均引用相同基表的视图。 有关将数据加载到视图的限制,请参见INSERT。

FROM 'data_file'

指定数据文件的完整路径,该数据文件包含要导入到指定表或视图中的数据。

BULK INSERT 可以从磁盘或Azure存储(包括网络存储、软盘、硬盘等)导入数据。

BULK INSERT bing_covid_19_data
FROM 'C:\\bing_covid-19_data\public\curated\covid-19\latest\bing_covid-19_data.csv';

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

BULK INSERT bing_covid_19_data
FROM '\\ShareX\bing_covid-19_data\public\curated\covid-19\latest\bing_covid-19_data.csv';

Azure SQL 数据库和 Fabric Data Warehouse 支持从 URI 读取数据,但不支持本地文件路径。

BULK INSERT bing_covid_19_data
FROM 'https://<data-lake>.blob.core.windows.net/public/curated/covid-19/bing_covid-19_data/latest/bing_covid-19_data.csv';

从 SQL Server 2017(14.x)开始, data_file 可以放在 Azure 存储中。 在这种情况下,还需要指定 data_source_name 选项。 举个例子,请参见 “从Azure存储文件导入数据”。

Fabric Data Warehouse 支持两种不同的路径样式来指定源路径:

  • https://<storage account>.blob.core.windows.net/<container name>/<path to file>
  • abfss://<container name>@<storage account>.dfs.core.windows.net/<path to file>

Fabric Data Warehouse 支持 * 可以匹配 URI 中任意字符的通配符,并允许你为应导入的文件定义 URI 模式。 例如:

BULK INSERT bing_covid_19_data
FROM 'https://<data-lake>.blob.core.windows.net/public/curated/covid-19/bing_covid-19_data/latest/*.csv';

备注

替换为 <data-lake>.blob.core.windows.net 相应的 URL。

数据源

适用于:SQL Server 2017(14.x)及以后版本、Azure SQL Database,以及 Microsoft Fabric 中的仓库。

指定一个指向文件导入的Azure Storage根位置的命名外部数据源。

CREATE EXTERNAL DATA SOURCE pandemicdatalake
WITH (LOCATION = 'https://<data-lake>.blob.core.windows.net/public/');

备注

替换为 <data-lake>.blob.core.windows.net 相应的 URL。

有关详细信息,请参阅 CREATE EXTERNAL DATA SOURCE

子句中的 FROM 文件路径必须是相对路径,该路径会附加到外部数据源中定义的根位置。

BULK INSERT bing_covid_19_data
FROM 'curated/covid-19/bing_covid-19_data/latest/bing_covid-19_data.csv'
WITH (DATA_SOURCE = 'pandemicdatalake', FIRSTROW = 2, LASTROW = 100, FIELDTERMINATOR = ',');

备注

为了简化起见,以下示例使用了相对路径和预定义的外部数据源。

CODEPAGE

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

BULK INSERT bing_covid_19_data
FROM '/curated/covid-19/bing_covid-19_data/latest/bing_covid-19_data.csv'
WITH (DATA_SOURCE = 'pandemicdatalake', FIRSTROW = 2, CODEPAGE = '65001');

CODEPAGE 在 Linux SQL Server 2017(14.x)上不支持该选项。 对于SQL Server 2019(15.x),只有'RAW'该选项被允许。CODEPAGE

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

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

SQL Server 2016(13.x)之前的版本不支持代码页 65001(UTF-8 编码)。
CODEPAGE 说明
ACP 数据类型为 charvarchartext 的列从 ANSI/Microsoft Windows 代码页 (ISO 1252) 转换为 SQL Server 代码页。
code_page 特定的代码页码,例如 850。

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

DATAFILETYPE

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

BULK INSERT bing_covid_19_data
FROM 'curated/covid-19/bing_covid-19_data/latest/bing_covid-19_data.csv'
WITH (DATA_SOURCE = 'pandemicdatalake', FIRSTROW = 2, DATAFILETYPE = 'char');

备注

替换为 <data-lake>.blob.core.windows.net 相应的 URL。

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

欲了解更多信息,请参见 使用字符格式导入或导出数据
widechar Unicode 字符。

欲了解更多信息,请参见 使用Unicode字符格式导入或导出数据
native 本机(数据库)数据类型。 通过使用 bcp 实用工具从 SQL Server 批量导入数据来创建本机数据文件。

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

欲了解更多信息,请参见 使用原生格式导入或导出数据
widenative 本机(数据库)数据类型,charvarchartext 列除外,这些列中的数据均以 Unicode 格式存储。 通过使用 widenative 工具批量导入 SQL Server 数据来创建数据文件。

widenative值为 提供了性能更高的替代方案。widechar 如果数据文件包含ANSI扩展字符,请指定 widenative

更多信息请参见 “使用Unicode本地格式导入或导出数据”。
DATAFILETYPE 所有数据表示于
char(默认值) 字符格式。

欲了解更多信息,请参见 使用字符格式导入或导出数据
widechar Unicode 字符。

欲了解更多信息,请参见 使用Unicode字符格式导入或导出数据

MAXERRORS(最大错误)

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

BULK INSERT bing_covid_19_data
FROM 'curated/covid-19/bing_covid-19_data/latest/bing_covid-19_data.csv'
WITH (DATA_SOURCE = 'pandemicdatalake', MAXERRORS = 0);

MAX_ERRORS选项不适用于约束检查或货币和双倍数据类型的转换。

错误文件

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

BULK INSERT bing_covid_19_data
FROM 'curated/covid-19/bing_covid-19_data/latest/bing_covid-19_data.csv'
WITH (DATA_SOURCE = 'pandemicdatalake',
      ERRORFILE = 'https://<data-lake>.blob.core.windows.net/public/curated/covid-19/bing_covid-19_data/latest/errors');

备注

替换为 <data-lake>.blob.core.windows.net 相应的 URL。

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

从 SQL Server 2017(14.x)开始, error_file_path 可以放在 Azure 存储中。

ERRORFILE_DATA_SOURCE

适用于:SQL Server 2017 (14.x) 及更高版本。

指定一个指向错误文件 Azure 存储位置的命名外部数据源,以跟踪导入过程中发现的错误。

BULK INSERT bing_covid_19_data
FROM 'curated/covid-19/bing_covid-19_data/latest/bing_covid-19_data.csv'
WITH (
    DATA_SOURCE = 'pandemicdatalake',
    ERRORFILE = 'curated/covid-19/bing_covid-19_data/latest/errors',
    ERRORFILE_DATA_SOURCE = 'pandemicdatalake'
);

有关创建外部数据源的更多细节,请参见 创建外部数据源

第一排

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

BULK INSERT bing_covid_19_data
FROM 'curated/covid-19/bing_covid-19_data/latest/bing_covid-19_data.csv'
WITH (DATA_SOURCE = 'pandemicdatalake', FIRSTROW = 2);

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

最后一条

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

批次大小

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

CHECK_CONSTRAINTS

指定在批量导入操作期间,必须检查所有对目标表或视图的约束。 如果没有该选项, CHECK_CONSTRAINTS 任意 CHECKFOREIGN KEY 约束会被忽略,作完成后,表上的约束被标记为不可信。

UNIQUE 并且 PRIMARY KEY 约束总是被强制执行。 当导入定义有 NOT NULL 约束的字符列时, BULK INSERT 如果文本文件中没有值,就会插入空字符串。

有时必须检查针对整个表的约束。 如果在批量导入作前表非空,重新验证约束的成本可能超过对增量数据应用 CHECK 约束的成本。

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

备注

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

触发器_启动

指定将在大容量导入操作期间执行目标表中定义的所有插入触发器。 如果目标表上的作定义了 INSERT 触发器,则每完成一批次触发触发。

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

KEEPIDENTITY

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

更多信息请参见“ 批量导入数据时保持身份值”。

KEEPNULLS

指定空列在大容量导入操作期间应保留 Null 值,而不插入列的任何默认值。 更多信息请参见 批量导入时保留空值或默认值

KILOBYTES_PER_BATCH

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

次序

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

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

ROWS_PER_BATCH

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

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

表锁

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

对于列存储索引,锁定行为有所不同,因为它在内部划分为多个行集。 每个线程通过对行集施加独占(X)锁,将数据专用加载到每个行集,允许并行数据加载并行加载会话。 使用 TABLOCK 选项会使线程对表施加独占锁(不同于传统行集的批量更新(BU)锁),防止其他并发线程同时加载数据。

输入文件格式选项

FORMAT

适用于:SQL Server 2017 (14.x) 及更高版本。

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

BULK INSERT bing_covid_19_data
FROM 'curated/covid-19/bing_covid-19_data/latest/bing_covid-19_data.csv'
WITH (DATA_SOURCE = 'pandemicdatalake', FORMAT = 'CSV');

在Fabric数据仓库中,语 BULK INSERT 句支持与语 COPY INTO 句相同的格式,因此 FORMAT = 'PARQUET' 也被支持。

现场引用

适用于:SQL Server 2017 (14.x) 及更高版本。

指定一个字符作为CSV文件中的引号字符。 如果未指定,引用字符"()将作为引号字符使用,按照 RFC 4180 标准的定义。

FORMATFILE

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

BULK INSERT bing_covid_19_data
FROM 'curated/covid-19/bing_covid-19_data/latest/bing_covid-19_data.csv'
WITH (DATA_SOURCE = 'pandemicdatalake',
      FORMATFILE = 'https://<data-lake>.blob.core.windows.net/public/curated/covid-19/bing_covid-19_data/latest/bing_covid-19_data.fmt');

备注

替换为 <data-lake>.blob.core.windows.net 相应的 URL。

在下列情况下应使用格式化文件:

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

从 SQL Server 2017(14.x)开始,在 Azure SQL 数据库中, format_file_path 可以安装在 Azure Storage。

FORMATFILE_DATA_SOURCE

适用于:SQL Server 2017 (14.x) 及更高版本。

指定一个命名的外部数据源,指向格式文件的 Azure 存储位置,以定义导入数据的模式。

BULK INSERT bing_covid_19_data
FROM 'curated/covid-19/bing_covid-19_data/latest/bing_covid-19_data.csv'
WITH (
    DATA_SOURCE = 'pandemicdatalake',
    FORMATFILE = 'curated/covid-19/bing_covid-19_data/latest/bing_covid-19_data.fmt',
    FORMATFILE_DATA_SOURCE = 'pandemicdatalake'
);

FIELDTERMINATOR

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

BULK INSERT bing_covid_19_data
FROM '/curated/covid-19/bing_covid-19_data/latest/bing_covid-19_data.csv'
WITH (DATA_SOURCE = 'pandemicdatalake', FIELDTERMINATOR = ',', FIRSTROW = 2);

ROWTERMINATOR

指定用于 charwidechar 数据文件的行终止符。

BULK INSERT bing_covid_19_data
FROM '/curated/covid-19/bing_covid-19_data/latest/bing_covid-19_data.csv'
WITH (DATA_SOURCE = 'pandemicdatalake', ROWTERMINATOR = '\r\n', FIRSTROW = 2);

默认的行终止符为 \r\n (回车和换行字符)。 有关详细信息,请参阅 “指定字段和行终止符”。

兼容性

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

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

数据类型

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

BULK INSERT 所用的字符串到十进制数据类型的转换遵循 Transact-SQL CONVERT 函数的规则,后者拒绝使用科学记号法表示数值的字符串。 因此,将 BULK INSERT 此类字符串视为无效值并报告转换错误。

若要绕过此行为,可使用格式化文件将以科学记数法表示的 float 数据批量导入小数列中。 在格式化文件中,请将列显式描述为 realfloat 数据。 关于这些数据类型的更多信息,请参见 float和实数

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

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

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

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

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

8.0000000000000002E-2 8.0000000000000002E-2

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

然而,不能 BULK INSERT 直接将这些数据导入 t_float,因为它的第二列 c2,使用 十 进制 数据类型。 因此,必须使用格式化文件。 格式化文件必须将以科学记数法表示的 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 数据库和 Fabric Data Warehouse 只支持从 URI(例如 Azure Storage)读取数据。

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

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

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

备注

关于语句、BULK INSERT语句和命令的INSERT ... SELECT * FROM OPENROWSET(BULK...)比较bcp,请参见“批量导入和导出数据”。

有关为大宗进口准备数据的信息,请参见 “为大宗出口或进口准备数据”。

BULK INSERT 语句可以在用户自定义事务中执行,将数据导入表或视图。 可选地,为了使用多匹配进行批量导入数据,事务可以在语句中指定该 BATCHSIZE 子句 BULK INSERT 。 如果回滚多批事务,发送到SQL Server的每一个批次都会被回滚。

互操作性

从 CSV 文件导入数据

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

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

日志行为

关于通过批量导入到 SQL Server 执行的行插入作何时被记录在事务日志中的信息,请参见批量 导入中最小日志的前置条件。 Azure SQL 数据库中不支持最小日志记录。

局限性

使用格式 BULK INSERT文件时,最多只能指定1024个字段。 这与表中允许的最大列数相同。 如果你使用包含 BULK INSERT 超过1024字段的数据文件格式文件, BULK INSERT 就会产生4822错误。 bcp 工具没有此限制,因此对于包含超过 1,024 字段的数据文件,可以不使用BULK INSERT格式文件,或者使用 bcp 命令。

性能注意事项

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

应在数据加载过程中测试各种批大小,以确定最佳方案。 请记住,批大小会影响部分回滚。 如果你的流程失败了,在再次使用 BULK INSERT 之前,你可能需要额外手动移除成功插入的行部分,避免失败。

对于Azure SQL Database,如果你导入大量数据,可以考虑在导入前暂时提高数据库或实例的性能水平。

安全性

安全帐户委托(模拟)

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

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

当你用BULK INSERTsqlcmdosql从一台电脑执行该语句,在另一台电脑上将数据插入SQL Server,并在第三台电脑上通过UNC路径指定data_file时,你可能会收到4861错误。

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

关于此及其他安全考虑 BULK INSERT的更多信息,请参见 使用 BULK INSERT 或 OPENROWSET(BULK...)导入数据到 SQL Server

当从Azure存储导入且数据不是公开(匿名访问)时,基于SAS密钥并用数据库主密钥(DMK)加密,创建一个数据库范围认证凭证,然后创建一个外部数据库源用于你的BULK INSERT命令。

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

重要

管理身份适用于Azure SQL以及SQL Server 2025(17.x)及更高版本。

权限

以下权限适用于数据被批量导入的地点(目标)。

要求 INSERTADMINISTER BULK OPERATIONS 权限。 在Azure SQL Database中, INSERTADMINISTER DATABASE BULK OPERATIONS 并且需要权限。 ADMINISTER BULK OPERATIONS Linux 上的 SQL Server 不支持权限或 批量管理员 角色。 只有 sysadmin 才能对 Linux 上的 SQL Server 执行批量插入。

此外,如果满足以下一项或多项条件,还需获得 ALTER TABLE 许可:

  • 存在约束,但 CHECK_CONSTRAINTS 选项没有被指定。

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

  • 触发器存在,但 FIRE_TRIGGER 选项没有具体说明。

    默认情况下,不会激发触发器。 要明确触发触发,请使用该 FIRE_TRIGGER 选项。

  • 你可以使用 KEEPIDENTITY 从数据文件导入身份值的选项。

示例

本文中的代码示例使用 AdventureWorks2025AdventureWorksDW2025 示例数据库,可以从 Microsoft SQL Server 示例和社区项目 主页下载该数据库。

重要

Azure SQL 数据库和 Fabric 仓库只支持从 Azure Storage 读取数据。

答: 使用竖线从文件导入数据

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

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

B. 使用 FIRE_TRIGGERS 参数

下面的示例指定 FIRE_TRIGGERS 参数。

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

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

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

DECLARE @bulk_cmd AS VARCHAR (1000);

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

EXECUTE (@bulk_cmd);

备注

在Windows上,会自动 \n 替换为 \r\n

D. 指定一个代码页

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

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

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 文件(使用 CODEPAGE65001),跳过标头(第一行),使用 ; 作为字段终止符,使用 0x0a 作为行终止符:

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

F. 从Azure Storage文件导入数据

在Azure存储中用SAS令牌加载CSV数据

以下示例展示了如何从你创建共享访问签名(SAS)的 Azure 存储位置的 CSV 文件加载数据。 Azure 存储位置被配置为外部数据源,这需要数据库范围的凭证,使用 SAS 密钥,并通过用户数据库中的 DMK 加密。

备注

确保你的SAS令牌没有引向, ? 并且至少对应加载 srt=o&sp=r的对象有读取权限,并且有效期是有效的(所有日期均为UTC时间)。

(可选)如果不需要 a DATABASE SCOPED CREDENTIAL ,就不需要 DMK,因为 blob 是设置为公开(匿名)访问。

CREATE MASTER KEY ENCRYPTION BY PASSWORD = '<password>';

(可选)不需要A DATABASE SCOPED CREDENTIAL ,因为blob配置为公开(匿名)访问。

不要在SAS令牌中包含前导 ? 。 确保你至少对应加载的对象有读取权限(srt=o&sp=r),并且有效期有效(所有日期均为UTC时间)。

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***************';

备注

CREDENTIAL 如果 blob 配置为公开(匿名)访问,则不需要。

CREATE EXTERNAL DATA SOURCE MyAzureBlobStorage
WITH (
    TYPE = BLOB_STORAGE,
    LOCATION = 'https://****************.blob.core.windows.net/invoices',
    CREDENTIAL = MyAzureBlobStorageCredential
);

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

从Azure存储中的CSV加载数据,并使用管理身份

以下示例展示了如何使用 BULK INSERT Managed Identity 从 Azure 存储位置的 CSV 文件加载数据的命令。 Azure 存储位置被配置为外部数据源。

(可选)如果不需要 a DATABASE SCOPED CREDENTIAL ,就不需要 DMK,因为 blob 是设置为公开(匿名)访问。

CREATE MASTER KEY ENCRYPTION BY PASSWORD = '<password>';

(可选)不需要A DATABASE SCOPED CREDENTIAL ,因为blob是为公开(匿名)访问配置的:

CREATE DATABASE SCOPED CREDENTIAL MyAzureBlobStorageCredential
WITH IDENTITY = 'Managed Identity';

授予存储 Blob 数据贡献者角色,以提供对所需 Azure 存储容器的管理身份的读写访问。

备注

CREDENTIAL 如果 blob 配置为公开(匿名)访问,则不需要。

CREATE EXTERNAL DATA SOURCE MyAzureBlobStorage
WITH (
    TYPE = BLOB_STORAGE,
    LOCATION = 'https://****************.blob.core.windows.net/invoices',
    CREDENTIAL = MyAzureBlobStorageCredential
);

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

重要

管理身份适用于SQL Server 2025(17.x)及以后版本,以及Azure SQL。

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

以下示例展示了如何从Azure存储位置的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 存储中批量访问数据的示例

更多示例

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