OPENROWSET BULK (Transact-SQL)

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

OPENROWSET T-SQL 命令包括从外部数据源访问远程数据所需的所有连接信息。 OPENROWSET 还通过内置的 BULK 提供程序支持大容量操作,正是有了该提供程序,才能从文件读取数据并将数据作为行集返回。 OPENROWSET BULK 用于从外部数据文件进行读取, OPENROWSET 不大容量用于从另一个数据库引擎进行读取。

OPENROWSET可以在查询的子句中FROM引用该函数,就好像它是表名一样。 OPENROWSET还可以将函数引用为受数据提供程序功能约束的 INSERTUPDATEDELETE语句的目标。 尽管查询可能返回多个结果集,但 OPENROWSET 只返回第一个结果集。

OPENROWSET BULK如果没有运算符,则仅在 SQL Server 上可用,有关详细信息,请参阅 OPENROWSET (Transact-SQL)

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

Transact-SQL 语法约定

Syntax

OPENROWSET(BULK) 语法用于读取外部文件:

OPENROWSET( BULK 'data_file' ,
            { FORMATFILE = 'format_file_path' [ <bulk_options> ]
              | SINGLE_BLOB | SINGLE_CLOB | SINGLE_NCLOB }
)

<bulk_options> ::=
   [ , DATA_SOURCE = 'data_source_name' ]

   -- bulk_options related to input file format
   [ , CODEPAGE = { 'ACP' | 'OEM' | 'RAW' | 'code_page' } ]
   [ , FORMAT = { 'CSV' | 'PARQUET' | 'DELTA' } ]
   [ , FIELDQUOTE = 'quote_character' ]
   [ , FORMATFILE = 'format_file_path' ]
   [ , FORMATFILE_DATA_SOURCE = 'data_source_name' ]

   [ , FIRSTROW = first_row ]
   [ , LASTROW = last_row ]

   [ , MAXERRORS = maximum_errors ]
   [ , ERRORFILE = 'file_name' ]
   [ , ERRORFILE_DATA_SOURCE = 'data_source_name' ]

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

Arguments

BULK arguments

BULK使用行集提供程序OPENROWSET从文件读取数据。 在 SQL Server 中,可以从数据文件中读取数据, OPENROWSET 而无需将数据加载到目标表中。 这使你可以与基本OPENROWSET语句一起使用SELECT

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

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

Note

用于使用完整恢复模式导入数据时, OPENROWSET (BULK ...) 不优化日志记录。

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

BULK 'data_file'

要将数据复制到目标表中的数据文件的完整路径。

SELECT * FROM OPENROWSET(
   BULK 'C:\DATA\inv-2017-01-19.csv',
   SINGLE_CLOB
) AS DATA;

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

BULK 错误处理选项

ERRORFILE = “file_name

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

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

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

ERRORFILE_DATA_SOURCE_NAME

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

MAXERRORS = maximum_errors

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

maximum_errors的默认值为 10。

Note

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

BULK 数据处理选项

DATA_SOURCE

DATA_SOURCE 是使用 CREATE EXTERNAL DATA SOURCE 创建的外部位置。

FIRSTROW = first_row

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

LASTROW = last_row

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

ROWS_PER_BATCH = rows_per_batch

指定数据文件中近似的数据行数量。 该值应与实际行数相同。

OPENROWSET 始终以单批形式导入数据文件。 但是,如果使用值 0 指定>,则查询处理器将使用 rows_per_batch 的值作为在查询计划中分配资源的提示。

默认情况下,ROWS_PER_BATCH 未知。 指定 ROWS_PER_BATCH = 0 与省 ROWS_PER_BATCH略相同。

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;

BULK 输入文件格式选项

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

指定该数据文件中数据的代码页。 CODEPAGE 仅当数据包含字符值超过 127 或小于 32 的 字符varchar文本 列时,才相关。

Important

CODEPAGE Linux 上不支持的选项。

Note

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

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

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

FORMAT = { 'CSV' |“PARQUET” |'DELTA' }

自 SQL Server 2017(14.x)起,此参数指定符合 RFC 4180 标准的逗号分隔值文件。

从 SQL Server 2022(16.x)开始,支持 Parquet 和 Delta 格式。

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

FORMATFILE = “format_file_path

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

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

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

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

FIELDQUOTE = “field_quote

自 SQL Server 2017(14.x)起,此参数指定 CSV 文件中用作引号字符的字符。 如果未指定,则引号字符 (") 用作 RFC 4180 标准中定义的引号字符。 只能将单个字符指定为此选项的值。

Remarks

OPENROWSET仅当为指定的提供程序显式设置为 0 注册表选项并且启用了即席分布式查询高级配置选项时,才可用于从 OLE DB 数据源访问远程数据。 如果未设置这些选项,则默认行为不允许临时访问。

访问远程 OLE DB 数据源时,不会从客户端连接到正在查询的服务器自动委派受信任连接的登录标识。 必须配置身份验证委托。

如果数据提供程序支持指定数据源中的多个目录和架构,则需要目录和架构名称。 catalog schema当数据提供程序不支持这些值时,可以省略这些值。 如果提供程序仅支持架构名称,则必须指定窗体 schema.object 的两部分名称。 如果提供程序仅支持目录名称,则必须指定表单 catalog.schema.object 的三部分名称。 有关详细信息,请参阅 Transact-SQL 语法约定

必须为使用 SQL Server Native Client OLE DB 提供程序的传递查询指定由三部分组成的名称。

OPENROWSET 不接受其参数的变量。

OPENDATASOURCE 子句中对 OPENQUERYOPENROWSETFROM 的任何调用与对用作更新目标的这些函数的任何调用都是分开独立计算的,即使为两个调用提供的参数相同也是如此。 具体而言,应用到上述任一调用的结果的筛选器或联接条件不会影响其他调用的结果。

将 OPENROWSET 与 BULK 选项配合使用

以下 Transact-SQL 增强功能支持该 OPENROWSET(BULK...) 函数:

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

    带有 OPENROWSET 选项的 BULKFROM 子句中需要有一个相关名称,也称为范围变量或别名。 可以指定列别名。 如果未指定列别名列表,则格式化文件必须具有列名。 指定列别名会覆盖格式化文件中的列名,例如:

    • FROM OPENROWSET(BULK...) AS table_alias
    • FROM OPENROWSET(BULK...) AS table_alias(column_alias,...n)

    Important

    如果添加 AS <table_alias> 失败,将导致错误:消息 491,级别 16,状态 1,第 20 行 必须在 FROM 子句中为大容量行集指定相关名称。

  • SELECT...FROM OPENROWSET(BULK...) 语句将直接查询文件中的数据,无需将数据导入表中。 SELECT...FROM OPENROWSET(BULK...) 语句还可以通过使用格式化文件指定列名和数据类型,从而列出大容量列别名。

  • OPENROWSET(BULK...) 用作 INSERTMERGE 语句中的源表,将数据文件中的数据大容量导入 SQL Server 表中。 有关详细信息,请参阅 使用 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)。 有关何时在事务日志中记录由批量导入执行的行插入操作的信息,请参阅批量导入的最小日志记录的先决条件

Note

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

批量导入 SQLCHAR、SQLNCHAR 或 SQLBINARY 数据

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

Note

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

批量导出或导入 SQLXML 文档

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

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

Permissions

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

  • ADMINISTER DATABASE BULK OPERATIONS

    or

  • ADMINISTER BULK OPERATIONS

以下示例向主体授予 ADMINISTEER DATABASE BULK OPERATIONS 权限。

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

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

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.CTP1_1\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;

More examples

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

适用于:Microsoft Fabric 中的 SQL 分析终结点和仓库

T-SQL OPENROWSET 函数读取 Azure Data Lake 存储中文件的内容。 可以读取存储在 Azure Data Lake 或 Azure Blob 存储中的文本/CSV、Parquet 或 JSON 行文件格式。

OPENROWSET 函数从文件读取数据,并将其作为行集返回。 OPENROWSET可以在查询的子句中FROM引用该函数,就好像它是表名一样。

本文仅适用于Microsoft Fabric Warehouse。 Fabric Warehouse 中的 OPENROWSET 函数和 SQL 分析终结点项之间存在功能差异。

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

Syntax

SELECT <columns>
FROM OPENROWSET(
    BULK 'https://<storage>.blob.core.windows.net/path/folder1=*/folder2=*/<filename>'
    [, FORMAT = ('PARQUET' | 'CSV' | 'JSONL') ]

    -- execution options
    [, ROWS_PER_BATCH=number_of_rows]

    -- Text/CSV encoding options
    [, DATAFILETYPE = {'char' | 'widechar' }     ]
    [, CODEPAGE = {'ACP' | 'OEM' | 'raw' | '<code_page>' } ]

    -- Text/CSV formatting options
    [, ROWTERMINATOR = 'row_terminator' ]
    [, FIELDTERMINATOR =  'field_terminator' ]
    [, FIELDQUOTE = 'string_delimiter' ]
    [ , PARSER_VERSION = 'parser_version' ]
    [, ESCAPECHAR = 'escape_char' ]
    [, HEADER_ROW = [true|false] ]
    [, FIRSTROW = first_row ]
    [, LASTROW = last_row ]

    -- execution options
    [, ROWS_PER_BATCH=number_of_rows]
) 
[
    WITH (  ( <column_name> <sql_datatype> [ '<column_path>' | <column_ordinal> ] )+ )
]
[ AS <alias> ]

Arguments

BULK 'data_file'

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

URI 可能包括 * 匹配任何字符序列的字符,从而允许 OPENROWSET 与 URI 进行模式匹配。 此外,它还可以结束 /** 以启用所有子文件夹的递归遍历。

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

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

Note

Fabric OneLake 存储以 预览版提供。 请参阅适用于COPY INTOOPENROWSET(BULK)适用的限制

支持的 URI 格式如下:

  • https://{storage}.blob.core.windows.net/[container}/{file path}
  • https://{storage}.dfs.core.windows.net/[container}/{file path}
  • abfss://[container}@{storage}.dfs.core.windows.net/{file path}
  • https://onelake.dfs.fabric.microsoft.com/<workspaceId>/<lakehouseId>/Files/{file path} - 当前处于 预览状态

For example:

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

BULK 输入文件格式选项

FORMAT = { 'CSV' |“PARQUET” |'JSONL' }

指定所引用文件的格式。 如果路径中的文件扩展名以 、、.csv.tsv.parquet.parq.jsonl.ldjson选项结尾.ndjsonFORMAT则不需要指定此选项。

Note

OPENROWSET 函数只能读取 换行分隔的 JSON 格式。 此功能目前处于预览状态。 换行符必须用作 JSON 文档之间的分隔符,不能放在 JSON 文档的中间。

For example:

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'
)

ROWS_PER_BATCH = rows_per_batch

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

For example:

SELECT TOP 10 *
FROM OPENROWSET(
    BULK 'abfss://public@pandemicdatalake.dfs.core.windows.net/curated/covid-19/bing_covid-19_data/latest/bing_covid-19_data.parquet',
    ROWS_PER_BATCH = 100000
);

文本/CSV 编码选项

DATAFILETYPE = { 'char' |“widechar” }

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

DATAFILETYPE value 表示的所有数据:
char (default) Character format.

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

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

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

指定该数据文件中数据的代码页。 CODEPAGE 仅当数据包含字符值超过 127 或小于 32 的 字符varchar文本 列时,才相关。

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

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

文本/CSV 格式设置选项

ROWTERMINATOR = “row_terminator

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

FIELDTERMINATOR = “field_terminator

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

例如,若要从文件读取制表符分隔的数据:

SELECT *
FROM OPENROWSET(
    BULK '{file path}',
    ROWTERMINATOR = '\t'
);

FIELDQUOTE = “field_quote

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

例如,在 FIELDQUOTE = '"' 以下逗号分隔值(CSV)数据集上使用,地址字段中有逗号。 地址字段的值将保留为单个值,而不是按 (quote) 字符中的 " 逗号拆分为多个值。

SELECT *
FROM OPENROWSET(
    BULK '{file path}',
    FIELDQUOTE = '"',
    FIELDTERMINATOR = ','
);
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"

PARSER_VERSION = "解析器版本"

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

  • PARSER_VERSION = '1.0'
  • 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”

指定文件中用于将自身及文件中所有分隔符值转义的字符。 如果转义字符后接除本身以外的某个值或者任何分隔符值,则读取值时会删除该转义字符。

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

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

SELECT *
FROM OPENROWSET(
    BULK '{file path}',
    ESCAPECHAR = '\'
);
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

HEADER_ROW = { TRUE |FALSE }

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

指定 CSV 文件是否包含不应与其他数据行一起返回的标头行。 默认值为 FALSE。 支持 PARSER_VERSION='2.0'。 如果 TRUE按参数从第一行 FIRSTROW 读取列名。 如果使用 TRUE 指定 WITH架构,则列名的绑定将由列名而不是序号位置完成。

SELECT *
FROM OPENROWSET(
    BULK '{file path}',
    HEADER_ROW = TRUE
);
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

FIRSTROW = first_row

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

LASTROW = last_row

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

Execution options

ROWS_PER_BATCH = rows_per_batch

指定数据文件中近似的数据行数量。 该值应与实际行数相同。

默认情况下,根据文件特征(文件数、文件大小、返回数据类型的大小)估计 ROWS_PER_BATCH。 指定 ROWS_PER_BATCH = 0 与省 ROWS_PER_BATCH略相同。

WITH Schema

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 子句中列的列的物理索引。

Remarks

表中汇总了支持的功能:

Feature Supported Not available
File formats 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() 函数。

Examples

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://synapseaisolutionsa.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 子对象中的嵌套属性。