批量访问 Azure Blob 存储中数据的示例

适用于: SQL Server 2017 (14.x) 及更高版本 Azure SQL 数据库

BULK INSERTOPENROWSET 语句可以直接访问 Azure Blob 存储中的文件。 下面的示例使用 CSV(逗号分隔值)文件(名为 inv-2017-01-19.csv)中的数据,该文件存储在容器(名为 Week3)中,该容器存储在存储帐户(名为 newinvoices)中。

Blob 存储上容器和文件的所有路径都区分大小写。 如果不正确,可能会返回如下所示的错误:

无法进行大容量加载。 文件 "file.csv" 不存在或没有文件访问权限。

创建凭据

必须借助一个使用 SHARED ACCESS SIGNATURE 标识的数据库范围凭据创建外部数据源。 若要为存储帐户创建共享访问签名 (SAS),请查看 Azure 门户中存储帐户属性页上的“共享访问签名”属性。 有关共享访问签名的详细信息,请参阅使用共享访问签名 (SAS) 授予对 Azure 存储资源的有限访问权限。 有关凭据的详细信息,请参阅 CREATE DATABASE SCOPED CREDENTIAL

使用必须是 SHARED ACCESS SIGNATUREIDENTITY 创建数据库范围凭据。 使用为 Blob 存储帐户生成的 SAS 令牌。 验证 SAS 令牌是否没有前导 ?、你是否至少对应加载的对象拥有读取权限以及有效期是否有效(所有日期都采用 UTC 时间)。

例如:

CREATE DATABASE SCOPED CREDENTIAL UploadInvoices
WITH IDENTITY = 'SHARED ACCESS SIGNATURE',
     SECRET = 'sv=2018-03-28&ss=b&srt=sco&sp=rwdlac&se=2019-08-31T02:25:19Z&st=2019-07-30T18:25:19Z&spr=https&sig=KS51p%2BVnfUtLjMZtUTW1siyuyd2nlx294tL0mnmFsOk%3D';

已知问题

使用 SAS 令牌从 Azure SQL 数据库和 Azure SQL 托管实例发出的请求可能因以下错误受阻止:

Msg 4861, Level 16, State 1, Line 27
Cannot bulk load because the file "FileName.extension" could not be opened. Operating system error code 5(Access is denied.).

受信任服务列表当前仅包含 Azure 服务的子集。 有关 Azure 存储防火墙设置的受信任服务和更新的完整列表,请参阅对订阅中注册的资源的受信任访问

示例

除了本文中的示例,还可以查看 GitHub 上的 Azure SQL 数据库导入数据示例

访问引用 Azure Blob 存储位置的 CSV 文件中的数据

下面的示例使用指向名为 MyAzureInvoices 的 Azure 存储帐户的外部数据源。

CREATE EXTERNAL DATA SOURCE MyAzureInvoices
WITH (
    TYPE = BLOB_STORAGE,
    LOCATION = 'https://newinvoices.blob.core.windows.net',
    CREDENTIAL = UploadInvoices
);

然后,OPENROWSET 语句将容器名称 (week3) 添加到文件说明。 该文件命名为 inv-2017-01-19.csv

SELECT * FROM OPENROWSET(
   BULK 'week3/inv-2017-01-19.csv',
   DATA_SOURCE = 'MyAzureInvoices',
   FORMAT = 'CSV',
   FORMATFILE = 'invoices.fmt',
   FORMATFILE_DATA_SOURCE = 'MyAzureInvoices'
) AS DataFile;

使用 BULK INSERT 时,请使用容器和文件说明:

BULK INSERT Colors2
FROM 'week3/inv-2017-01-19.csv'
WITH (DATA_SOURCE = 'MyAzureInvoices', FORMAT = 'CSV');

访问引用 Azure Blob 存储位置中某个容器的 CSV 文件中的数据

下面的示例使用指向 Azure 存储帐户中某个容器(名为 week3)的外部数据源。

CREATE EXTERNAL DATA SOURCE MyAzureInvoicesContainer
WITH (
    TYPE = BLOB_STORAGE,
    LOCATION = 'https://newinvoices.blob.core.windows.net/week3',
    CREDENTIAL = UploadInvoices
);

OPENROWSET 语句不会在文件说明中包含该容器名称:

SELECT * FROM OPENROWSET(
   BULK 'inv-2017-01-19.csv',
   DATA_SOURCE = 'MyAzureInvoicesContainer',
   FORMAT = 'CSV',
   FORMATFILE = 'invoices.fmt',
   FORMATFILE_DATA_SOURCE = 'MyAzureInvoices'
) AS DataFile;

使用 BULK INSERT 时,请不要在文件说明中使用该容器名称:

BULK INSERT Colors2
FROM 'inv-2017-01-19.csv'
WITH (DATA_SOURCE = 'MyAzureInvoicesContainer', FORMAT = 'CSV');