SQL 代理作业中的批量插入失败,未找到文件

Posted

技术标签:

【中文标题】SQL 代理作业中的批量插入失败,未找到文件【英文标题】:Bulk Insert fails in SQL Agent Job, FILE NOT FOUND 【发布时间】:2016-06-28 15:52:21 【问题描述】:

这类问题我有好几个条目,但似乎没有一个能为我解决。

My SQL SERVER 和 SQL SERVER AGENT 服务都设置为同一个用户帐户。

我有一个存储过程,它执行以下操作(删除了错误检查)

exec XP_CMDSHELL 'net use P: \\machine/share password /user:machine\user'
exec XP_CMDSHELL 'dir p: /b /a-d-h-s > p:\dir.txt'

CREATE TABLE #FilesTemp ( Filename varchar(200) )

BULK INSERT #FilesTemp
FROM 'p:\dir.txt'
WITH
    (
        ROWTERMINATOR = '\n'
    )

当我从 SSMS 运行存储过程时,它运行良好。当我通过作业运行它时,XP_CMDSHELL 调用正常工作并创建了“dir.txt”文件。但是批量插入失败并出现错误 3 (p:\dir.txt not found)。

我已登录 SSMS,使用“sa”连接到 SQL Server,并且该作业归 sa 所有。正在创建共享的用户具有必要的权限。

更多信息:

有一条评论(然后显然已删除)询问我是否正在从服务器计算机运行 SSMS。我试过了。

显然,当我使用 Windows 身份验证运行时,批量插入失败,但在将存储过程作为 SA 运行时,它可以工作。代理正在使用 Windows 身份验证运行并失败。

但是为什么呢?我无法理解安全问题。

有什么想法吗?

【问题讨论】:

【参考方案1】:

虽然您正在使用映射驱动器为映射驱动器创建安全性,但您不能使用映射驱动器进行批量插入。

但是您可以使用 UNC 路径,但安全性是 SQL Server 帐户的安全性。

请注意,/share 旁边有一个斜杠,我认为这是一个错字

exec XP_CMDSHELL 'net use P: \\machine\share password /user:machine\user'
exec XP_CMDSHELL 'dir p: /b /a-d-h-s > p:\dir.txt'


exec Xp_cmdshell  'move p:\dir.txt c:\dir.txt'


CREATE TABLE #FilesTemp ( Filename varchar(200) )

BULK INSERT #FilesTemp
FROM 'c:\dir.txt'
WITH
    (
        ROWTERMINATOR = '\n'
    )

当 BULK INSERT 命令由使用 SQL Server 的登录发起时 身份验证,与数据的连接是使用安全性进行的 SQL Server 进程帐户的上下文(SQL 使用的帐户) 服务器数据库引擎服务)。成功读取源数据 您必须授予 SQL Server 数据库引擎使用的帐户, 访问源数据。相反,如果 SQL Server 用户通过以下方式登录 使用 Windows 身份验证,用户只能读取那些 可以通过用户帐户访问,无论安全性如何 SQL Server 进程的配置文件

https://msdn.microsoft.com/en-us/library/ms188365.aspx

【讨论】:

不幸的是,我在尝试时遇到了登录错误。 问题是大容量复制是在 SQL Server 的安全上下文中完成的。您不能使用映射驱动器,只能使用 unc 路径。如果无法授予服务器帐户访问权限,则将角色复制到本地驱动器并从那里导入 显然,当使用 sa 登录到 SQL Server 时,它运行良好。请参阅更新后的帖子。因此,它可以使用映射的驱动器。但是,显然存在安全问题。 当以 sa 运行时,它会恢复到服务器 Windows 进程帐户。但是当作为作业运行时,它使用的是较低级别的帐户。您可以将作业更改为以 sa 身份运行并重新测试吗? 我正在尝试,但不知道该怎么做。有一个运行方式,但它是空白的。谷歌声称这与代理有关,但我找不到 sa 代理。

以上是关于SQL 代理作业中的批量插入失败,未找到文件的主要内容,如果未能解决你的问题,请参考以下文章

如何从 SQL *PLUS 中的批量插入中查找失败的插入语句

MyCat批量插入

Oracle 批量插入数据怎么做

Python批量插入问题?

Oracle 批量插入数据怎么做

批量从Dataframe插入到DB,忽略Pyspark中的失败行