[英]OPENROWSET BULK behaviour and lack of an ERRORFILE when it goes wrong
[英]Issue with ERRORFILE when BULK INSERTing from Azure Blob Storage
我正在尝试将大量 CSV 文件从 Azure Blob 存储批量插入到我的 Azure SQL 数据库中。
这是我试图实现这一目标的方法:
IF EXISTS(SELECT * FROM SYSOBJECTS WHERE ID = OBJECT_ID('[sqldb1].[dbo].[TABLE_A_RAW]'))
DROP TABLE [sqldb1].[dbo].[TABLE_A_RAW];
CREATE TABLE [sqldb1].[dbo].[TABLE_A_RAW]
(
[COL1] varchar(60),
[COL2] varchar(60),
[COL3] varchar(60),
[COL4] varchar(60),
[COL5] varchar(60)
);
BULK INSERT [sqldb1].[dbo].[TABLE_A_RAW]
FROM 'TABLE_A.CSV'
WITH
(
DATA_SOURCE = 'myazureblobstoragecontainer',
FORMAT = 'CSV',
ERRORFILE = 'load_errors_TABLE_A',
ERRORFILE_DATA_SOURCE = 'myazureblobstoragecontainer',
FIRSTROW = 2,
FIELDTERMINATOR = '0xE29691',
ROWTERMINATOR = '0x0a'
)
GO
IF EXISTS(SELECT * FROM SYSOBJECTS WHERE ID = OBJECT_ID('[sqldb1].[dbo].[TABLE_B_RAW]'))
DROP TABLE [sqldb1].[dbo].[TABLE_B_RAW];
CREATE TABLE [sqldb1].[dbo].[TABLE_B_RAW]
(
[COL1] varchar(60),
[COL2] varchar(60),
[COL3] varchar(60),
[COL4] varchar(60),
[COL5] varchar(60),
[COL6] varchar(60),
[COL7] varchar(60),
[COL8] varchar(60),
[COL9] varchar(60)
);
BULK INSERT [sqldb1].[dbo].[TABLE_B_RAW]
FROM 'TABLE_B.CSV'
WITH
(
DATA_SOURCE = 'myazureblobstoragecontainer',
FORMAT = 'CSV',
ERRORFILE = 'load_errors_TABLE_B',
ERRORFILE_DATA_SOURCE = 'myazureblobstoragecontainer',
FIRSTROW = 2,
FIELDTERMINATOR = '0xE29691',
ROWTERMINATOR = '0x0a'
)
GO
上面的代码是在我从事几乎相同的项目(具有相同的部署)时开发的,并且没有任何问题。 当我尝试为当前项目运行上面的代码时,错误日志文件被创建,表也是如此(如预期),但它们都是空的,我收到这些错误:
消息 4861,级别 16,状态 1,第 17 行
无法批量加载,因为无法打开文件“load_errors_TABLE_A”。 操作系统错误代码 80(文件存在。)。消息 4861,级别 16,状态 1,第 17 行
无法批量加载,因为无法打开文件“load_errors_TABLE_A.Error.Txt”。 操作系统错误代码 80(文件存在。)。Msg 4861, Level 16, State 1, Line 50
无法批量加载,因为无法打开文件“load_errors_TABLE_B”。 操作系统错误代码 80(文件存在。)。Msg 4861, Level 16, State 1, Line 50
无法批量加载,因为无法打开文件“load_errors_TABLE_B.Error.Txt”。 操作系统错误代码 80(文件存在。)。
错误文件仅在我运行上面的代码时创建,这意味着它们在运行上面的代码之前不存在,如错误消息所示。 当我注释掉说ERRORFILE
和ERRORFILE_DATA_SOURCE
(即ERRORFILE = 'load_errors_TABLE_A',
, ERRORFILE = 'load_errors_TABLE_B',
, 和ERRORFILE_DATA_SOURCE = 'myazureblobstoragecontainer',
)并再次运行脚本而没有任何错误时,批量插入完成(但显然错误文件最终不会被创建)。
我想BULK INSERT
WITH ERRORFILE
s,以便我可以跟踪操作期间发生的任何截断,就像我在之前的项目中所做的那样。 我尝试寻找类似的帖子,但它们似乎都与本地BULK INSERT
操作有关,其中错误日志文件也在本地创建/存储。 正如我上面提到的,前一个项目和这个项目的部署几乎相同 - 它们都运行 SQL Server 2014 (12.0.2000.8),我对 Azure DB 和 Blob 存储帐户 + 容器都有读/写访问权限。
CREATE DATABASE SCOPED CREDENTIAL UploadInvoices
WITH IDENTITY = 'SHARED ACCESS SIGNATURE',
SECRET = 'sv=2019-12-12******2FspTCY%3D'
我已经尝试了以下测试,效果很好。 我的 csv 文件没有标题。
CREATE MASTER KEY ENCRYPTION BY PASSWORD = '***';
go
CREATE DATABASE SCOPED CREDENTIAL UploadInvoices
WITH IDENTITY = 'SHARED ACCESS SIGNATURE',
SECRET = 'sv=2019-12-12&ss=bfqt&srt=sco&sp******%2FspTCY%3D'; -- dl
CREATE EXTERNAL DATA SOURCE MyAzureInvoices
WITH (
TYPE = BLOB_STORAGE,
LOCATION = 'https://***.blob.core.windows.net/<container_name>',
CREDENTIAL = UploadInvoices
);
BULK INSERT production.customer
FROM 'bs140513_032310-demo.csv'
WITH
(
DATA_SOURCE = 'MyAzureInvoices',
FORMAT = 'CSV',
ERRORFILE = 'load_errors_TABLE_B',
ERRORFILE_DATA_SOURCE = 'MyAzureInvoices',
FIRSTROW = 2
)
GO
正如@joseph-xu 在下面的回答中所建议的那样,罪魁祸首最终是权限。
当前的项目:
旧项目:
我在此项目中使用的 Blob 存储的 SAS 键缺少DELETE
和DELETE VERSION
权限,如果您想在BULK INSERT
语句中包含ERRORFILE
和ERRORFILE_DATA_SOURCE
,这是必要的。 据我所知,这在微软的文档中没有提到(并且错误消息也没有暗示这是问题所在)。
我只是创建了一个具有 ALL 权限的新 SAS 密钥,用它来创建一个新的DATABASE SCOPED CREDNETIAL
和EXTERNAL DATA SOURCE
,然后再次运行我的代码并且它工作正常。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.