Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/80.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 在存储过程中将文件写入网络驱动器_Sql_Sql Server - Fatal编程技术网

Sql 在存储过程中将文件写入网络驱动器

Sql 在存储过程中将文件写入网络驱动器,sql,sql-server,Sql,Sql Server,我有一个存储过程,可以使用BCP将文件写入网络驱动器,方法是在数据库服务器上创建一个临时驱动器,映射到另一台服务器上的共享驱动器。它工作正常,但是,我从上一个EXEC命令返回了一个错误,它说在与U:.的连接上有打开的文件和/或未完成的目录搜索。我猜它正在试图在完成文件写入之前执行delete drive命令。如果在运行proc之后运行该语句,它将成功删除驱动器。以下是程序: CREATE PROCEDURE dn_ExportFile @ServerName varchar(50),

我有一个存储过程,可以使用BCP将文件写入网络驱动器,方法是在数据库服务器上创建一个临时驱动器,映射到另一台服务器上的共享驱动器。它工作正常,但是,我从上一个
EXEC
命令返回了一个错误,它说
在与U:.的连接上有打开的文件和/或未完成的目录搜索。我猜它正在试图在完成文件写入之前执行delete drive命令。如果在运行proc之后运行该语句,它将成功删除驱动器。以下是程序:

CREATE PROCEDURE dn_ExportFile
    @ServerName varchar(50),
    @ServerPath varchar(500),
    @FileName varchar(100),
    @Query varchar(max),
    @UserName varchar(100),
    @Password varchar(100),
    @Drive varchar(1) = 'U'
AS
BEGIN
    SET NOCOUNT ON;

    DECLARE @cmd VARCHAR(8000)

    --Set up virtual drive pointing to desired path
    SET @cmd = 'NET USE ' + @Drive + ': ' + @ServerPath + ' /user:' + @ServerName + '\' + @UserName + ' ' + @Password
    PRINT @cmd
    EXEC xp_cmdshell @cmd

    --Export data using BCP to virtual drive
    SET @cmd = 'BCP "' + @Query + '" QUERYOUT "' + @Drive + ':\' + @FileName + '" -c -t -T'
    PRINT @cmd
    EXEC xp_cmdshell @cmd

    --Delete virtual drive
    SET @cmd = 'NET USE ' + @Drive + ': /delete'
    PRINT @cmd
    EXEC xp_cmdshell @cmd
END

有没有方法可以成功删除存储过程中的临时驱动器?

我怀疑在调用过程仍在作用域内时无法执行此操作。因此,您可以尝试一个包装器存储过程,它可以:

EXEC dbo.dn_ExportFile ...;

SET @cmd = 'NET USE ' + @Drive + ': /delete';
PRINT @cmd;
EXEC xp_cmdshell @cmd;

否则我仍然认为你在错误的地方做这件事。让调用此过程的程序调用命令并指定路径。

虽然我建议使用程序的查询结果,而不是让SQL Server直接写入网络驱动器,但这可能只是时间问题。您是否尝试添加
等待延迟'00:00:05'在最后一个命令之前?是的,我尝试了延迟,但它没有执行trickI同意从程序使用文件系统要容易得多,但我希望此过程能够工作,以便我可以在SQL Server代理作业中使用它。你是对的,它不在进程内工作,因为你建议的修复确实有效。我想知道是否有某种方法可以手动“关闭”BCP文件,或者SQL Server代理作业可以像调用存储过程一样轻松地调用cmd exe或PowerShell脚本。我不认为这与“关闭”BCP文件有任何关系,这是过程调用的进程仍然保留着共享驱动器。这就是为什么当程序超出范围时它会工作的原因。谢谢你的帮助,我将开始进行你描述的设置。但是,目前为止,我发现在命令后面附加“/y”,它会通过对提示“是否可以继续断开并强制关闭它们?(y/N)[N]:”回答“是”来强制断开连接again@WillP. 啊,有趣的是,很高兴有一个更直接的解决方案(我从来没有想到会有某种要抑制的提示-通常,如果程序正在等待输入,它会完全挂起存储过程)。