BULK INSERT 在我有权访问的文件上收到“无法批量加载,因为......访问被拒绝”

Ken*_*her 7 sql-server sql-server-2008-r2 sql-server-2016 bulk-insert

我正在尝试运行 BULK INSERT,但出现访问被拒绝错误。到目前为止,我已经尝试了以下方法:

  • 我可以从我的机器打开文件
  • 我使用 windows auth 登录到 SQL Server(尝试过 v2008 R2 和 v2016)
  • 我有系统管理员权限
  • 我可以type使用 xp_cmdshell 文件(使用 SQL 服务帐户,但它消除了它是防火墙的想法)
  • 路径是网络 URL,而不是本地驱动器

我使用的命令是这样的:

BULK INSERT ken_temp
FROM '\\network_path\temp\kdf\text_file.txt'
WITH
   (
    FIELDTERMINATOR = ',', ROWTERMINATOR = '\n'
   ,ROWS_PER_BATCH = 50000
   ,MAXERRORS = 10
   )
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?

Sol*_*zky 6

问题在于:

  1. 您正在使用 Windows 身份验证登录:这意味着 SQL Server 将尝试模拟您的 Windows/域帐户以进行文件系统访问。

  2. 您已直接登录到工作站,然后远程连接到 SQL Server:这意味着您通过将身份验证令牌从工作站传递到运行 SQL Server 的服务器间接连接到运行 SQL Server 的服务器。

  3. 您尚未为 SQL Server 启用委派:这意味着您坚持默认行为,即不允许在直接登录后 1 步之后传递该令牌。

  4. 您正在尝试读取远程资源上存在的文件:这意味着它比您直接登录的位置多 1 步。

这就是为什么您可以从工作站正常访问文件的原因。这就是为什么 usingxp_cmdshell也有效的原因,因为服务帐户直接登录到运行 SQL Server 的服务器,而远程资源仅一步之遥。

我怀疑如果您将远程桌面直接连接到运行 SQL Server 的服务器,在该服务器上运行 SSMS,然后执行BULK INSERT,它会成功。或者,如果您设置 SQL Server 登录,授予登录“批量管理员”权限,然后EXECUTE AS Login = 'JustReadTheDangFileAlready';,然后执行BULK INSERT. 当作为 SQL Server 登录执行BULK INSERT/ 时OPENROWSET (BULK...),没有要模拟的 Windows 帐户,因此文件系统访问是使用服务帐户完成的,就像xp_cmdshell.

您有以下选择:

  1. 为 SQL Server 启用委派(不记得是针对服务还是帐户,在这种情况下,可能是您的 Windows 帐户需要它,但有关于如何设置的指南,其中包括设置 SPN) . 我相信这是首选/推荐的选择。这允许进程将身份验证令牌转发到进一步从直接登录中删除的资源。

  2. 在此过程中使用 SQL Server 登录。我不敢相信我的建议,但是如果您的 SQL Server 登录名处于“批量管理员”固定服务器角色或具有正确的“批量管理员”权限,那么您可以为此创建关联的用户登录(在适当的数据库中),并将 放入BULK INSERT使用WITH EXECUTE AS 'JustReadTheDangFileAlready'. 然后你可以执行那个应该屏蔽请求来自 Windows 帐户的 proc。

  3. 打开该远程文件的权限(也许还有文件夹?)。您可以向“所有人”授予“读取”权限(也可以授予“读取”权限或对该文件夹的其他一些权限)。

  4. 删除此问题并使用此“错误”作为需要昂贵 SAN 的理由,该 SAN 将通过 HBA 卡连接并显示为本地驱动器?。只需告诉 CFO:“这真的是唯一的方法。互联网是这么说的。”