OPENROWSET BULK (Transact-SQL)

适用于:SQL ServerAzure SQL 数据库Azure SQL 托管实例Microsoft Fabric 中的 SQL 分析终结点Microsoft Fabric 中的仓库

OPENROWSET 函数从一个或多个文件读取数据,并将内容作为行集返回。 根据服务的不同,该文件可能存储在 Azure Blob 存储、Azure Data Lake 存储、本地磁盘、网络共享等中。可以读取各种文件格式,例如文本/CSV、Parquet 或 JSON 行。

OPENROWSET可以在查询的子句中FROM引用该函数,就好像它是表名一样。 它可用于读取语句中的数据SELECT,或更新 、UPDATEINSERTDELETEMERGECTAS语句中的CETAS目标数据。

  • OPENROWSET(BULK) 专为从外部数据文件读取数据而设计。
  • OPENROWSET 没有 BULK 设计用于从另一个数据库引擎读取。 有关详细信息,请参阅 OPENROWSET(Transact-SQL)。

本文和平台之间的 OPENROWSET(BULK) 参数集各不相同。

其他平台上类似示例的详细信息和链接:

Transact-SQL 语法约定

SQL Server、Azure SQL 数据库和 Azure SQL 托管实例的语法

OPENROWSET( BULK 'data_file_path',
            <bulk_option> ( , <bulk_option> )*
)
[
    WITH (  ( <column_name> <sql_datatype> [ '<column_path>' | <column_ordinal> ] )+ )
]

<bulk_option> ::=
   DATA_SOURCE = 'data_source_name' |

   -- file format options
   CODEPAGE = { 'ACP' | 'OEM' | 'RAW' | 'code_page' } |
   DATAFILETYPE = { 'char' | 'widechar' } |
   FORMAT = <file_format> |

   FORMATFILE = 'format_file_path' |
   FORMATFILE_DATA_SOURCE = 'data_source_name' |

   SINGLE_BLOB |
   SINGLE_CLOB |
   SINGLE_NCLOB |

   -- Text/CSV options
   ROWTERMINATOR = 'row_terminator' |
   FIELDTERMINATOR =  'field_terminator' |
   FIELDQUOTE = 'quote_character' |

   -- Error handling options
   MAXERRORS = maximum_errors |
   ERRORFILE = 'file_name' |
   ERRORFILE_DATA_SOURCE = 'data_source_name' |

   -- Execution options
   FIRSTROW = first_row |
   LASTROW = last_row |

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

   ROWS_PER_BATCH = rows_per_batch

Fabric 数据仓库的语法

OPENROWSET( BULK 'data_file_path',
            <bulk_option> ( , <bulk_option> )*
)
[
    WITH (  ( <column_name> <sql_datatype> [ '<column_path>' | <column_ordinal> ] )+ )
]

<bulk_option> ::=
   DATA_SOURCE = 'data_source_name' |

   -- file format options
   CODEPAGE = { 'ACP' | 'OEM' | 'RAW' | 'code_page' } |
   DATAFILETYPE = { 'char' | 'widechar' } |
   FORMAT = <file_format> |

   -- Text/CSV options
   ROWTERMINATOR = 'row_terminator' |
   FIELDTERMINATOR =  'field_terminator' |
   FIELDQUOTE = 'quote_character' |
   ESCAPECHAR = 'escape_char' |
   HEADER_ROW = [true|false] |
   PARSER_VERSION = 'parser_version' |

   -- Error handling options
   MAXERRORS = maximum_errors |
   ERRORFILE = 'file_name' |

   -- Execution options
   FIRSTROW = first_row |
   LASTROW = last_row |

   ROWS_PER_BATCH = rows_per_batch

Arguments

该选项的参数 BULK 允许对开始和结束读取数据的位置、如何处理错误以及解释数据的方式进行重大控制。 例如,可以指定数据文件读取为 varbinaryvarcharnvarchar 类型的单行单列行集。 默认行为详见随后的参数说明。

有关如何使用 BULK 选项的信息,请参阅本文后面的“ 备注 ”部分。 有关该选项所需的权限 BULK 的信息,请参阅本文后面的 “权限” 部分。

有关准备数据进行批量导入的信息,请参阅 准备数据进行批量导出或导入

BULK “data_file_path

要读取和返回其数据作为行集的数据文件的路径或 URI。

URI 可以引用 Azure Data Lake 存储或 Azure Blob 存储。 要读取和返回其数据作为行集的数据文件的 URI。

支持的路径格式为:

  • <drive letter>:\<file path> 访问本地磁盘上的文件
  • \\<network-share\<file path> 访问网络共享上的文件
  • adls://<container>@<storage>.dfs.core.windows.net/<file path> 访问 Azure Data Lake Storage
  • abs://<storage>.blob.core.windows.net/<container>/<file path> 访问 Azure Blob 存储
  • s3://<ip-address>:<port>/<file path> 访问与 s3 兼容的存储

Note

本文和支持的 URI 模式在不同平台上有所不同。 对于 Microsoft Fabric 数据仓库中可用的 URI 模式, 请在版本下拉列表中选择 Fabric

从 SQL Server 2017 (14.x)开始, data_file 可以位于 Azure Blob 存储中。 有关示例,请参阅Azure Blob 存储中批量访问数据的示例。

  • https://<storage>.blob.core.windows.net/<container>/<file path> 访问 Azure Blob 存储或 Azure Data Lake Storage
  • https://<storage>.dfs.core.windows.net/<container>/<file path> 访问 Azure Data Lake Storage
  • abfss://<container>@<storage>.dfs.core.windows.net/<file path> 访问 Azure Data Lake Storage
  • https://onelake.dfs.fabric.microsoft.com/<workspaceId>/<lakehouseId>/Files/<file path> - 访问 Fabric OneLake (目前为 预览版

Note

本文和支持的 URI 模式在不同平台上有所不同。 对于 SQL Server、Azure SQL 数据库和 Azure SQL 托管实例中可用的 URI 模式, 请在版本下拉列表中选择该产品

URI 可以包含 * 与任何字符序列匹配的字符,从而允许 OPENROWSET 与 URI 进行模式匹配。 此外,它还可以结束 /** 以启用所有子文件夹的递归遍历。 在 SQL Server 中,此行为从 SQL Server 2022(16.x)开始可用。

例如:

SELECT TOP 10 *
FROM OPENROWSET(
    BULK '<scheme:>//pandemicdatalake.blob.core.windows.net/public/curated/covid-19/bing_covid-19_data/latest/*.parquet'
);

下表显示了 URI 可以引用的存储类型:

版本 本地 Azure 存储 Fabric OneLake S3 Google Cloud (GCS)
SQL Server 2017 (14.x)、SQL Server 2019 (15.x) 是的 是的
SQL Server 2022 (16.x) 是的 是的 是的
Azure SQL 数据库 是的
Azure SQL 托管实例 是的
Azure Synapse Analytics 中的无服务器 SQL 池 是的 是的
Microsoft Fabric Warehouse 和 SQL 分析终结点 是的 是(预览版) 是(预览),使用 Fabric OneLake 快捷方式 是(预览),使用 Fabric OneLake 快捷方式

可用于 OPENROWSET(BULK) 直接从存储在 Fabric OneLake 中的文件读取数据,特别是从 Fabric Lakehouse 的 Files 文件夹中 读取数据。 这样就无需使用外部暂存帐户(例如 ADLS Gen2 或 Blob 存储),并使用 Fabric 权限启用工作区管理的 SaaS 本机引入。 此功能支持:

  • Files Lakehouses 中的文件夹读取
  • 同一租户中的工作区到仓库负载
  • 使用 Microsoft Entra ID 的本机标识强制实施

Note

访问 Fabric OneLake 存储以 预览版提供。 请参阅适用于COPY INTO适用的OPENROWSET(BULK)

DATA_SOURCE

DATA_SOURCE 定义数据文件路径的根位置。 它使你可以在 BULK 路径中使用相对路径。 使用 CREATE EXTERNAL DATA SOURCE 创建数据源。

除了根位置之外,还可以定义可用于访问该位置上的文件的自定义凭据。

例如:

CREATE EXTERNAL DATA SOURCE root
WITH (LOCATION = '<scheme:>//pandemicdatalake.blob.core.windows.net/public')
GO
SELECT *
FROM OPENROWSET(
    BULK '/curated/covid-19/bing_covid-19_data/latest/*.parquet',
    DATA_SOURCE = 'root'
);

Note

此选项 DATA_SOURCE 在 Microsoft Fabric Warehouse 和 SQL 分析终结点中 处于预览 状态。

文件格式选项

CODEPAGE

指定该数据文件中数据的代码页。 CODEPAGE 仅当数据包含字符值超过 127 或小于 32 的 字符varchar文本 列时,才相关。 有效值为“ACP”、“OEM”、“RAW”或“code_page”:

CODEPAGE 值 Description
ACP charvarchar文本 数据类型的列从 ANSI/Microsoft Windows 代码页(ISO 1252)转换为 SQL Server 代码页。
OEM(默认值) charvarchar文本 数据类型的列从系统 OEM 代码页转换为 SQL Server 代码页。
RAW 不执行从一个代码页到另一个代码页的转换。 这是执行最快的选项。
code_page 指示数据文件中字符数据已编码的源代码页,例如 850。

Important

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

Note

我们建议为格式文件中的每个列指定一个排序规则名称,除非你希望 65001 选项优先于排序规则/代码页规范。

DATAFILETYPE

指定 OPENROWSET(BULK) 应读取单字节(ASCII、UTF8)或多字节(UTF16)文件内容。 有效值为 charwidechar

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

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

有关详细信息,请参阅 使用 Unicode 字符格式导入或导出数据

FORMAT

指定所引用文件的格式,例如:

SELECT *
FROM OPENROWSET(BULK N'<data-file-path>',
                FORMAT='CSV') AS cars;

有效值为“CSV”( 符合 RFC 4180 标准版的逗号分隔值文件)、“PARQUET”、“DELTA”(版本 1.0)和“JSONL”,具体取决于版本:

版本 CSV 拼花地板 德尔塔 JSONL
SQL Server 2017 (14.x)、SQL Server 2019 (15.x) 是的
SQL Server 2022 (16.x) 及更高版本 是的 是的 是的
Azure SQL 数据库 是的 是的 是的
Azure SQL 托管实例 是的 是的 是的
Azure Synapse Analytics 中的无服务器 SQL 池 是的 是的 是的
Microsoft Fabric Warehouse 和 SQL 分析终结点 是的 是的 是的

Important

OPENROWSET 函数只能读取 换行分隔的 JSON 格式。 换行符必须用作 JSON 文档之间的分隔符,不能放在 JSON 文档的中间。

FORMAT如果路径中的文件扩展名以 、、.csv.tsv.parquet.parq.jsonl或或.ldjson结尾.ndjson,则不需要指定该选项。 例如,该 OPENROWSET(BULK) 函数知道格式是基于以下示例中的扩展的 parquet:

SELECT *
FROM OPENROWSET(
    BULK 'https://pandemicdatalake.blob.core.windows.net/public/curated/covid-19/bing_covid-19_data/latest/bing_covid-19_data.parquet'
);

如果文件路径未以下列扩展名之一结尾,则需要指定一个 FORMAT,例如:

SELECT TOP 10 *
FROM OPENROWSET(
      BULK 'abfss://nyctlc@azureopendatastorage.blob.core.windows.net/yellow/**',
      FORMAT='PARQUET'
)

FORMATFILE

指定格式化文件的完整路径。 SQL Server 支持两种格式化文件类型:XML 和非 XML。

SELECT TOP 10 *
FROM OPENROWSET(
      BULK 'D:\XChange\test-csv.csv',
      FORMATFILE= 'D:\XChange\test-format-file.xml'
)

格式化文件对定义结果集中的列类型是必需的。 唯一的例外是,SINGLE_CLOBSINGLE_BLOBSINGLE_NCLOB指定;在这种情况下,不需要格式化文件。

有关格式化文件的信息,请参阅使用格式化文件批量导入数据(SQL Server)。

从 SQL Server 2017 (14.x) 开始,format_file_path 可位于 Azure Blob 存储中。 有关示例,请参阅Azure Blob 存储中批量访问数据的示例。

FORMATFILE_DATA_SOURCE

FORMATFILE_DATA_SOURCE 定义格式化文件路径的根位置。 它使你可以在 FORMATFILE 选项中使用相对路径。

CREATE EXTERNAL DATA SOURCE root
WITH (LOCATION = '//pandemicdatalake/public/curated')
GO
SELECT *
FROM OPENROWSET(
    BULK '//pandemicdatalake/public/curated/covid-19/bing_covid-19_data/latest/bing_covid-19_data.csv'
    FORMATFILE = 'covid-19/bing_covid-19_data/latest/bing_covid-19_data.fmt',
    FORMATFILE_DATA_SOURCE = 'root'
);

格式化文件数据源是使用 CREATE EXTERNAL DATA SOURCE 创建的。 除了根位置之外,还可以定义可用于访问该位置上的文件的自定义凭据。

文本/CSV 选项

ROWTERMINATOR

指定要用于 charwidechar 数据文件的行终止符,例如:

SELECT *
FROM OPENROWSET(
    BULK '<data-file-path>',
    ROWTERMINATOR = '\n'
);

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

FIELDTERMINATOR

指定要用于 charwidechar 数据文件的字段终止符,例如:

SELECT *
FROM OPENROWSET(
    BULK '<data-file-path>',
    FIELDTERMINATOR = '\t'
);

默认字段终止符为 , (逗号)。 有关详细信息,请参阅 指定字段和行终止符。 例如,若要从文件读取制表符分隔的数据:

FIELDQUOTE = “field_quote

自 SQL Server 2017(14.x)起,此参数指定在 CSV 文件中用作引号字符的字符,如以下纽约示例所示:

Empire State Building,40.748817,-73.985428,"20 W 34th St, New York, NY 10118","\icons\sol.png"
Statue of Liberty,40.689247,-74.044502,"Liberty Island, New York, NY 10004","\icons\sol.png"

只能将单个字符指定为此选项的值。 如果未指定,则引号字符 (") 用作 RFC 4180 标准中定义的引号字符。 字符 FIELDTERMINATOR (例如,逗号)可以放在字段引号中,它将被视为用 FIELDQUOTE 字符包装的单元格中的常规字符。

例如,若要读取以前的纽约示例 CSV 数据集,请使用 FIELDQUOTE = '"'。 地址字段的值将保留为单个值,而不是按 (quote) 字符中的 " 逗号拆分为多个值。

SELECT *
FROM OPENROWSET(
    BULK '<data-file-path>',
    FIELDQUOTE = '"'
);

PARSER_VERSION = "解析器版本"

适用于: Fabric 数据仓库

指定读取文件时要使用的分析器版本。 当前支持 CSV 分析器版本为 1.0 和 2.0:

  • PARSER_VERSION = '1.0'
  • PARSER_VERSION = '2.0'
SELECT TOP 10 *
FROM OPENROWSET(
      BULK 'abfss://nyctlc@azureopendatastorage.blob.core.windows.net/yellow/**',
      FORMAT='CSV',
      PARSER_VERSION = '2.0'
)

CSV 分析器版本 1.0 是默认版本且功能丰富。 版本 2.0 是为提高性能而构建的,并不支持所有选项和编码。

CSV 分析器版本 1.0 详细信息:

  • 不支持以下选项:HEADER_ROW。
  • 默认终止符为 \r\n\n 并且 \r
  • 如果将 指定\n为行终止符(换行符),则会自动为其\r添加前缀(回车符),这将导致行终止符。\r\n

CSV 分析器版本 2.0 详细信息:

  • 不是所有数据类型都受支持。
  • 最大字符列长度为 8000。
  • 最大行大小限制为 8 MB。
  • 不支持以下选项: DATA_COMPRESSION
  • 带引号的空字符串 ("") 被解释为空字符串。
  • DATEFORMAT SET 选项未被执行。
  • 日期数据类型支持的格式:YYYY-MM-DD
  • 时间数据类型支持的格式:HH:MM:SS[.fractional seconds]
  • datetime2 数据类型支持的格式:YYYY-MM-DD HH:MM:SS[.fractional seconds]
  • 默认终止符为 \r\n\n

ESCAPE_CHAR = “char”

指定文件中用于转义自身和文件中所有分隔符值的字符,例如:

Place,Address,Icon
Empire State Building,20 W 34th St\, New York\, NY 10118,\\icons\\sol.png
Statue of Liberty,Liberty Island\, New York\, NY 10004,\\icons\\sol.png

如果转义字符后接除本身以外的某个值或者任何分隔符值,则读取值时会删除该转义字符。

ESCAPECHAR无论是否启用参数FIELDQUOTE,都会应用该参数。 不会使用该参数来转义引号字符。 必须使用其他引号字符来转义引号字符。 仅当用引号字符封装值时,引用字符才会出现在列值内。

在以下示例中,逗号 (,) 和反斜杠 (\) 被转义并表示为 \,\\

SELECT *
FROM OPENROWSET(
    BULK '<data-file-path>',
    ESCAPECHAR = '\'
);

HEADER_ROW = { TRUE |FALSE }

指定 CSV 文件是否包含不应与其他数据行一起返回的标头行。 以下示例显示了包含标头的 CSV 文件示例:

Place,Latitude,Longitude,Address,Area,State,Zipcode
Empire State Building,40.748817,-73.985428,20 W 34th St,New York,NY,10118
Statue of Liberty,40.689247,-74.044502,Liberty Island,New York,NY,10004

默认值为 FALSE。 支持 PARSER_VERSION='2.0'。 如果 TRUE按参数从第一行 FIRSTROW 读取列名。 如果使用 TRUE 指定 WITH架构,则列名的绑定将由列名而不是序号位置完成。

SELECT *
FROM OPENROWSET(
    BULK '<data-file-path>',
    HEADER_ROW = TRUE
);

错误处理选项

ERRORFILE = “file_name

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

SELECT *
FROM OPENROWSET(
    BULK '<data-file-path>',
    ERRORFILE = '<error-file-path>'
);

错误文件在开始执行命令时创建。 如果文件已存在,则会引发错误。 此外,还创建了一个扩展名为 .ERROR.txt 的控制文件。 此文件引用错误文件中的每一行并提供错误诊断。 更正错误后,可以加载数据。

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

ERRORFILE_DATA_SOURCE

从 SQL Server 2017 (14.x)开始,此参数是一个命名的外部数据源,指向错误文件的位置,该文件将包含导入过程中发现的错误。

CREATE EXTERNAL DATA SOURCE root
WITH (LOCATION = '<root-error-file-path>')
GO
SELECT *
FROM OPENROWSET(
    BULK '<data-file-path>',
    ERRORFILE = '<relative-error-file-path>',
    ERRORFILE_DATA_SOURCE = 'root'
);

有关详细信息,请参阅 CREATE EXTERNAL DATA SOURCE (Transact-SQL)

MAXERRORS = maximum_errors

指定格式化文件中定义的最大语法错误数或不符合的行数,在引发异常之前 OPENROWSET 可能发生。 在到达之前 MAXERRORSOPENROWSET 请忽略每个错误的行,不加载该行,并将错误行计数为一个错误。

SELECT *
FROM OPENROWSET(
    BULK '<data-file-path>',
    MAXERRORS = 0
);

maximum_errors的默认值为 10。

Note

MAX_ERRORS 不适用于 CHECK 约束或转换 货币bigint 数据类型。

数据处理选项

FIRSTROW = first_row

指定要加载的第一行的行号。 默认值为 1。 这表示指定数据文件中的第一行。 通过对行终止符进行计数来确定行号。 FIRSTROW 基于 1。

LASTROW = last_row

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

ROWS_PER_BATCH = rows_per_batch

指定数据文件中近似的数据行数量。 此值是一个估计值,应是实际行数的一个近似值(以一个数量级表示)。 默认情况下,根据文件特征(文件数、文件大小、返回数据类型的大小)估计 ROWS_PER_BATCH。 指定 ROWS_PER_BATCH = 0 与省 ROWS_PER_BATCH略相同。 例如:

SELECT TOP 10 *
FROM OPENROWSET(
    BULK '<data-file-path>',
    ROWS_PER_BATCH = 100000
);

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

一个用于指定数据文件中数据的排序方式的可选提示。 默认情况下,大容量操作假定数据文件未排序。 如果查询优化器可以利用顺序生成更高效的查询计划,则性能会提高。 以下列表提供了指定排序可能有益的示例:

  • 将行插入到具有聚集索引的表,其中行集数据按聚集索引键进行排序。
  • 将行集与另一个表联接,其中排序列和联接列匹配。
  • 通过排序列聚合行集数据。
  • 将行集用作查询子句中的 FROM 源表,其中排序列和联接列匹配。

UNIQUE

指定数据文件没有重复条目。

如果数据文件中的实际行未根据指定的顺序进行排序,或者 UNIQUE 指定提示并且存在重复键,则返回错误。

使用列别名时 ORDER 是必需的。 列别名列表必须引用子句正在访问的 BULK 派生表。 子句中指定的 ORDER 列名引用此列别名列表。 无法指定大型值类型(varchar(max)nvarchar(max)varbinary(max)和大型对象(LOB)类型(textntextimage) 列。

内容选项

SINGLE_BLOB

varbinary(max)类型的单行单列行集的形式返回data_file的内容。

Important

建议仅使用 SINGLE_BLOB 选项(而不是 SINGLE_CLOBSINGLE_NCLOB)导入 XML 数据,因为仅 SINGLE_BLOB 支持所有 Windows 编码转换。

SINGLE_CLOB

通过将 data_file 作为 ASCII 读取,使用当前数据库的排序规则将内容作为 varchar(max)类型的单行单列行集返回。

SINGLE_NCLOB

通过将 data_file 读取为 Unicode,使用当前数据库的排序规则将内容作为 nvarchar(max)类型的单行单列行集返回。

SELECT * FROM OPENROWSET(
    BULK N'C:\Text1.txt',
    SINGLE_NCLOB
) AS Document;

WITH 架构

WITH 架构指定定义 OPENROWSET 函数的结果集的列。 它包括将作为结果返回的每个列的列定义,并概述了将基础文件列绑定到结果集中的列的映射规则。

在下面的示例中:

  • country_region 列具有 varchar(50) 类型,并引用具有相同名称的基础列
  • date 列引用具有不同物理名称的 CSV/Parquet 列或 JSONL 属性
  • cases 列引用文件中的第三列
  • fatal_cases 列引用嵌套的 Parquet 属性或 JSONL 子对象
SELECT *
FROM OPENROWSET(<...>) 
WITH (
        country_region varchar(50), --> country_region column has varchar(50) type and referencing the underlying column with the same name
        [date] DATE '$.updated',   --> date is referencing a CSV/Parquet column or JSONL property with a different physical name
        cases INT 3,             --> cases is referencing third column in the file
        fatal_cases INT '$.statistics.deaths'  --> fatal_cases is referencing a nested Parquet property or JSONL sub-object
     );

<column_name>

将在结果行集中返回的列的名称。 除非 <column_path><column_ordinal>重写,否则此列的数据将从具有相同名称的基础文件列读取。 列的名称必须遵循 列名称标识符的规则

<column_type>

结果集中列的 T-SQL 类型。 当 OPENROWSET 返回结果时,基础文件中的值将转换为此类型。 有关详细信息,请参阅 Fabric Warehouse 中的数据类型

<column_path>

用于引用复杂类型(例如 Parquet)中的嵌套字段的点分隔路径(例如 $.description.location.lat)。

<column_ordinal>

一个数字,表示将映射到 WITH 子句中列的列的物理索引。

Permissions

OPENROWSET 具有外部数据源,需要以下权限:

  • ADMINISTER DATABASE BULK OPERATIONS
  • ADMINISTER BULK OPERATIONS

以下 T-SQL 示例向主体授予 ADMINISTER DATABASE BULK OPERATIONS

GRANT ADMINISTER DATABASE BULK OPERATIONS TO [<principal_name>];

如果目标存储帐户是专用的,则主体还必须在容器或存储帐户级别分配存储 Blob 数据读取者 角色(或更高版本)。

Remarks

  • FROM 配合使用的 SELECT 子句可以调用具有完整 OPENROWSET(BULK...) 功能的 SELECT,而不是表名。

  • 带有 OPENROWSET 选项的 BULKFROM 子句中需要有一个相关名称,也称为范围变量或别名。 未能在 AS <table_alias> 错误 Msg 491 中添加结果:“必须为 from 子句中的大容量行集指定关联名称。

  • 可以指定列别名。 如果未指定列别名列表,则格式化文件必须具有列名。 指定列别名会覆盖格式化文件中的列名,例如:

    • FROM OPENROWSET(BULK...) AS table_alias
    • FROM OPENROWSET(BULK...) AS table_alias(column_alias,...n)
  • SELECT...FROM OPENROWSET(BULK...) 语句将直接查询文件中的数据,无需将数据导入表中。

  • 语句 SELECT...FROM OPENROWSET(BULK...) 可以使用格式化文件指定列名和数据类型来列出大容量列别名。

  • OPENROWSET(BULK...)或语句中INSERTMERGE用作源表时,将数据从数据文件批量导入表中。 有关详细信息,请参阅 使用 BULK INSERT 或 OPENROWSET(BULK...)将数据导入 SQL Server
  • OPENROWSET BULK 选项与语句一 INSERT 起使用时,子 BULK 句支持表提示。 除了常规表提示(例如 TABLOCK),BULK 子句还可以接受以下专用表提示:IGNORE_CONSTRAINTS(仅忽略 CHECKFOREIGN KEY 约束)、IGNORE_TRIGGERSKEEPDEFAULTSKEEPIDENTITY。 有关详细信息,请参阅表提示 (Transact-SQL)
  • 有关如何使用 INSERT...SELECT * FROM OPENROWSET(BULK...) 语句的信息,请参阅批量导入和导出数据 (SQL Server)。 有关何时在事务日志中记录由批量导入执行的行插入操作的信息,请参阅批量导入的最小日志记录的先决条件
  • 用于使用完整恢复模式导入数据时, OPENROWSET (BULK ...) 不优化日志记录。

Note

使用 OPENROWSET时,请务必了解 SQL Server 如何处理模拟。 有关安全注意事项的信息,请参阅 使用 BULK INSERT 或 OPENROWSET(BULK...)将数据导入 SQL Server

在 Microsoft Fabric 中,表中汇总了受支持的功能:

Feature Supported 不可用
文件格式 Parquet、CSV、JSONL Delta、Azure Cosmos DB、JSON、关系数据库
Authentication EntraID/SPN 直通、公共存储 SAS/SAK、SPN、托管访问
Storage Azure Blob 存储、Azure Data Lake Storage、Fabric OneLake(预览版)
Options 仅包含完整/绝对 URI OPENROWSET 中的 OPENROWSET相对 URI 路径, DATA_SOURCE
Partitioning 可以在查询中使用 filepath() 函数。

批量导入 SQLCHAR、SQLNCHAR 或 SQLBINARY 数据

OPENROWSET(BULK...)假定如果未指定,则最大长度SQLCHARSQLNCHARSQLBINARY或数据长度不超过 8,000 字节。 如果导入的数据位于包含任何 varchar(max)nvarchar(max)varbinary(max) 对象超过 8,000 字节的 LOB 数据字段中,则必须使用定义数据字段最大长度的 XML 格式化文件。 若要指定最大长度,请编辑格式文件并声明 MAX_LENGTH 属性。

Note

自动生成的格式化文件未指定 LOB 字段的长度或最大长度。 不过,您可以手动编辑格式文件并指定长度或最大长度。

批量导出或导入 SQLXML 文档

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

数据类型 Effect
SQLCHARSQLVARYCHAR 数据在客户端代码页或排序规则隐含的代码页中发送。
SQLNCHARSQLNVARCHAR 以 Unicode 格式发送数据。
SQLBINARYSQLVARYBIN 不经任何转换即发送数据。

Examples

本部分提供一般示例来演示如何使用 OPENROWSET BULK 语法。

A. 使用 OPENROWSET 将文件数据批量插入 varbinary(max) 列

适用于: 仅限 SQL Server。

以下示例创建一个小表用于演示目的,并将位于根目录中的文件Text1.txtC:的文件数据插入 varbinary(max) 列。

CREATE TABLE myTable (
    FileName NVARCHAR(60),
    FileType NVARCHAR(60),
    Document VARBINARY(MAX)
);
GO

INSERT INTO myTable (
    FileName,
    FileType,
    Document
)
SELECT 'Text1.txt' AS FileName,
    '.txt' AS FileType,
    *
FROM OPENROWSET(
    BULK N'C:\Text1.txt',
    SINGLE_BLOB
) AS Document;
GO

B. 使用带格式化文件的 OPENROWSET BULK 提供程序从文本文件中检索行

适用于: 仅限 SQL Server。

以下示例使用格式化文件检索用制表符分隔的文本文件 values.txt 中的行,该文件包含下列数据:

1     Data Item 1
2     Data Item 2
3     Data Item 3

格式化文件 values.fmt 说明 values.txt 中的列:

9.0
2
1  SQLCHAR  0  10 "\t"    1  ID           SQL_Latin1_General_Cp437_BIN
2  SQLCHAR  0  40 "\r\n"  2  Description  SQL_Latin1_General_Cp437_BIN

此查询检索该数据:

SELECT a.* FROM OPENROWSET(
    BULK 'C:\test\values.txt',
   FORMATFILE = 'C:\test\values.fmt'
) AS a;

C. 指定格式化文件和代码页

适用于: 仅限 SQL Server。

以下示例演示如何同时使用格式化文件和代码页选项。

INSERT INTO MyTable
SELECT a.* FROM OPENROWSET (
    BULK N'D:\data.csv',
    FORMATFILE = 'D:\format_no_collation.txt',
    CODEPAGE = '65001'
) AS a;

D. 使用格式化文件从 CSV 文件访问数据

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

SELECT * FROM OPENROWSET(
    BULK N'D:\XChange\test-csv.csv',
    FORMATFILE = N'D:\XChange\test-csv.fmt',
    FIRSTROW = 2,
    FORMAT = 'CSV'
) AS cars;

E. 在没有格式化文件的情况下从 CSV 文件访问数据

适用于: 仅限 SQL Server。

SELECT * FROM OPENROWSET(
   BULK 'C:\Program Files\Microsoft SQL Server\MSSQL14\MSSQL\DATA\inv-2017-01-19.csv',
   SINGLE_CLOB
) AS DATA;
SELECT *
FROM OPENROWSET('MSDASQL',
    'Driver={Microsoft Access Text Driver (*.txt, *.csv)}',
    'SELECT * FROM E:\Tlog\TerritoryData.csv'
);

Important

ODBC 驱动程序应为 64 位。 在 Windows 中打开“连接到 ODBC 数据源”(SQL Server 导入和导出向导)应用程序的“驱动程序”选项卡以验证这一点。 有 32 位 Microsoft Text Driver (*.txt, *.csv) 不能与 64 位版本的版本 sqlservr.exe一起使用。

F. 从存储在 Azure Blob 存储 上的文件中访问数据

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

在 SQL Server 2017(14.x)及更高版本中,以下示例使用一个外部数据源,该数据源指向 Azure 存储帐户中的容器,以及为共享访问签名创建的数据库范围凭据。

SELECT * FROM OPENROWSET(
   BULK 'inv-2017-01-19.csv',
   DATA_SOURCE = 'MyAzureInvoices',
   SINGLE_CLOB
) AS DataFile;

有关包括配置凭据和外部数据源在内的完整OPENROWSET示例,请参阅Azure Blob 存储中批量访问数据的示例。

G. 从存储在 Azure Blob 存储 上的文件中导入表

以下示例演示如何使用 OPENROWSET 命令从创建 SAS 密钥的 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 = '<password>';
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***************';

-- Make sure that you don't have a leading ? in the 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/curriculum',
    -- CREDENTIAL is not required if a blob is configured for public (anonymous) access!
    CREDENTIAL = MyAzureBlobStorageCredential
);

INSERT INTO achievements
WITH (TABLOCK) (
    id,
    description
)
SELECT * FROM OPENROWSET(
    BULK 'csv/achievements.csv',
    DATA_SOURCE = 'MyAzureBlobStorage',
    FORMAT = 'CSV',
    FORMATFILE = 'csv/achievements-c.xml',
    FORMATFILE_DATA_SOURCE = 'MyAzureBlobStorage'
) AS DataFile;

H. 将托管标识用于外部源

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

以下示例使用托管标识创建凭据,创建外部源,然后从托管在外部源上的 CSV 加载数据。

首先,创建凭据并将 Blob 存储指定为外部源:

CREATE DATABASE SCOPED CREDENTIAL sampletestcred
WITH IDENTITY = 'MANAGED IDENTITY';

CREATE EXTERNAL DATA SOURCE SampleSource
WITH (
    LOCATION = 'abs://****************.blob.core.windows.net/curriculum',
    CREDENTIAL = sampletestcred
);

接下来,从托管在 Blob 存储上的 CSV 文件加载数据:

SELECT * FROM OPENROWSET(
    BULK 'Test - Copy.csv',
    DATA_SOURCE = 'SampleSource',
    SINGLE_CLOB
) as test;

I. 使用 OPENROWSET 使用与 S3 兼容的对象存储访问多个 Parquet 文件

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

以下示例使用从不同位置访问多个 Parquet 文件,这些文件都存储在与 S3 兼容的对象存储上:

CREATE DATABASE SCOPED CREDENTIAL s3_dsc
WITH IDENTITY = 'S3 Access Key',
SECRET = 'contosoadmin:contosopwd';
GO

CREATE EXTERNAL DATA SOURCE s3_eds
WITH
(
    LOCATION = 's3://10.199.40.235:9000/movies',
    CREDENTIAL = s3_dsc
);
GO

SELECT * FROM OPENROWSET(
    BULK (
        '/decades/1950s/*.parquet',
        '/decades/1960s/*.parquet',
        '/decades/1970s/*.parquet'
    ),
    FORMAT = 'PARQUET',
    DATA_SOURCE = 's3_eds'
) AS data;

J. 使用 OPENROWSET 从 Azure Data Lake Gen2 访问多个 Delta 表

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

在此例中,数据表容器命名为 Contoso,位于 Azure Data Lake Gen2 存储帐户中。

CREATE DATABASE SCOPED CREDENTIAL delta_storage_dsc
WITH IDENTITY = 'SHARED ACCESS SIGNATURE',
SECRET = '<SAS Token>';

CREATE EXTERNAL DATA SOURCE Delta_ED
WITH (
    LOCATION = 'adls://<container>@<storage_account>.dfs.core.windows.net',
    CREDENTIAL = delta_storage_dsc
);

SELECT *
FROM OPENROWSET(
    BULK '/Contoso',
    FORMAT = 'DELTA',
    DATA_SOURCE = 'Delta_ED'
) AS result;

K. 使用 OPENROWSET 查询公共匿名数据集

以下示例使用公开提供的 NYC 黄色出租车行程记录打开数据集

首先创建数据源:

CREATE EXTERNAL DATA SOURCE NYCTaxiExternalDataSource
WITH (LOCATION = 'abs://nyctlc@azureopendatastorage.blob.core.windows.net');

在与名称模式匹配的文件夹中使用扩展名查询所有文件 .parquet

SELECT TOP 10 *
FROM OPENROWSET(
 BULK 'yellow/puYear=*/puMonth=*/*.parquet',
 DATA_SOURCE = 'NYCTaxiExternalDataSource',
 FORMAT = 'parquet'
) AS filerows;

A. 从 Azure Blob 存储读取 parquet 文件

在以下示例中,可以看到如何从 Parquet 文件读取 100 行:

SELECT TOP 100 * 
FROM OPENROWSET(
    BULK 'https://pandemicdatalake.blob.core.windows.net/public/curated/covid-19/bing_covid-19_data/latest/bing_covid-19_data.parquet'
);

B. 读取自定义 CSV 文件

在以下示例中,可以看到如何使用标题行和显式指定的终止符字符从 CSV 文件中读取行和分隔行和字段的行:

SELECT *
FROM OPENROWSET(
BULK 'https://pandemicdatalake.blob.core.windows.net/public/curated/covid-19/bing_covid-19_data/latest/bing_covid-19_data.csv',
 HEADER_ROW = TRUE,
 ROW_TERMINATOR = '\n',
 FIELD_TERMINATOR = ',');

C. 读取文件时指定文件列架构

在以下示例中,可以看到如何显式指定将作为函数返回 OPENROWSET 的行的架构:

SELECT *
FROM OPENROWSET(
BULK 'https://pandemicdatalake.blob.core.windows.net/public/curated/covid-19/bing_covid-19_data/latest/bing_covid-19_data.parquet') 
WITH (
        updated DATE
        ,confirmed INT
        ,deaths INT
        ,iso2 VARCHAR(8000)
        ,iso3 VARCHAR(8000)
        );

D. 读取分区数据集

在以下示例中,可以看到如何使用 filepath() 函数从匹配的文件路径中读取 URI 的各个部分:

SELECT TOP 10 
  files.filepath(2) AS area
, files.*
FROM OPENROWSET(
BULK 'https://<storage account>.blob.core.windows.net/public/NYC_Property_Sales_Dataset/*_*.csv',
 HEADER_ROW = TRUE) 
AS files
WHERE files.filepath(1) = '2009';

E. 读取 JSONL 文件时指定文件列架构

在以下示例中,可以看到如何显式指定将作为函数返回的 OPENROWSET 行的架构:

SELECT TOP 10 *
FROM OPENROWSET(
BULK 'https://pandemicdatalake.dfs.core.windows.net/public/curated/covid-19/bing_covid-19_data/latest/bing_covid-19_data.jsonl') 
WITH (
        country_region varchar(50),
        date DATE '$.updated',
        cases INT '$.confirmed',
        fatal_cases INT '$.deaths'
     );

如果列名与属性中的列的物理名称不匹配(如果 JSONL 文件)匹配,则可以在类型定义后在 JSON 路径中指定物理名称。 可以使用多个属性。 例如, $.location.latitude 若要引用 parquet 复杂类型或 JSON 子对象中的嵌套属性。

更多示例

更多示例

有关显示使用 OPENROWSET(BULK...)的示例,请参阅以下文章: