4

我正在使用一个调用 xp_cmdshell 的 SQL 存储过程。xp_cmdshell 已启用,并且代理帐户设置为“vpexporter”。该存储过程旨在将数据文件写入磁盘。

该存储过程在 SQL 2005 服务器上时一直在工作。环境已升级到 SQL 2012,sproc 不再运行。拨打电话的线路是:

set @sql1 = 'bcp "SELECT * FROM dbo.udPayrollOutput" queryout "D:\Repository\Exports\' + @fileunique  -Uvpexporter -Ppassword -c -t,' 
exec master..xp_cmdshell @sql1

在 SSMS 中运行它会给我以下信息:

SQLState = 28000。NativeError = 18456 错误 = [Microsoft][SQL Server Native Client 11.0][SQL Server]用户“vpexporter”登录失败。

我已经使用 SQL 登录名和域帐户进行了尝试。两者都返回相同的错误。'vpexporter' 已添加为登录名,并已设置为主数据库的用户,对 xp_cmdshell 具有执行权限。

我觉得使用 SQL 版本 2012 调用 xp_cmdshell 的方式肯定发生了一些变化,但是在谷歌搜索时我没有发现任何东西。

我尝试运行“exec xp_cmdshell 'whoami.exe'”,它返回了“nt authority\network service”,这是 SQL Server 正在运行的帐户。

我的理解是,通过使用“sp_xp_cmdshell_proxy_account”指定命令外壳代理帐户,它会改用它。我不想授予 xp_cmdshell 对网络服务的执行访问权限。


我已经取得了一些进展,但仍然卡住了。最初的错误是由于新环境需要通过在我的查询行中添加“-S ServerName\InstanceName”来指定 SQL 实例。我现在得到错误:

无法启动“cvADPTaxCreditExp”存储过程。对象“xp_cmdshell”、数据库“mssqlsystemresource”、模式“sys”的执行权限被拒绝。

我已将 master 中的 xp_cmdshell 的执行权限授予代理帐户,但仍然收到此错误。

exec sp_xp_cmdshell_proxy_account 'NEWMECHDOM\vpexporter', 'password';
GRANT EXECUTE ON xp_cmdshell TO [NEWMECHDOM\vpexporter];

我已经用这个验证了它:

select  * from  sys.credentials

是否还有其他地方需要设置安全性?

4

2 回答 2

4

bcp.exe我在 SQL Server 2008 R2 机器上运行的批处理文件中使用时遇到了同样的问题:指定用户/密码-U -P返回“NativeError = 18456”(登录失败),我使用“受信任的连接”和参数解决了它-T

BCP.EXE错误 18456 的调用是:

bcp.exe "SELECT * from DWH.BS.flussi.vw_KLINX_Anagrafiche800" queryout %fname% -t";" -c -SLOCALHOST -dMEF -Uxxx -Pyyy

BCP.EXE工作电话是:

bcp.exe "SELECT * from DWH.BS.flussi.vw_KLINX_Anagrafiche800" queryout %fname% -t";" -c -SLOCALHOST -dMEF -Uxxx -Pyyy -T
于 2016-04-26T09:57:50.157 回答
0

我发现 2008 和 2012 不一样。在 2008 中我不需要指定服务器名称。在 2008 年,我还可以使用 D$ 来使用驱动器号,但现在我需要使用共享驱动器名称。以下作品于 2012 年进行。

-- Declare report variables
DECLARE @REPORT_DIR VARCHAR(4000)
DECLARE @REPORT_FILE VARCHAR(100)
DECLARE @DATETIME_STAMP VARCHAR(14)
DECLARE @Statement VARCHAR(4000)
DECLARE @Command VARCHAR(4000)

--SET variables for the Report File
SET @DATETIME_STAMP = (SELECT CONVERT(VARCHAR(10), GETDATE(), 112) + 
REPLACE(CONVERT(VARCHAR(8), GETDATE(),108),':','')) -- Date Time Stamp with YYYYMMDDHHMMSS
SET @REPORT_DIR = '\\aServerName\SharedDirectory\' -- Setting where to send the report. The Server name and a Shared name, not a drive letter
SET @REPORT_FILE = @REPORT_DIR + 'Tables_' + @DATETIME_STAMP + '.csv' --the -t below is used for the csv file

--创建包含所有数据的 CSV 文件报告。@Statement 变量必须用于在 xp_cmdshell 命令中使用变量。

SET @Statement = '"SELECT * FROM  sys.tables" queryout "'+@REPORT_FILE+'" -c -t"," -r"\n" -S"CurrentServerName\Databasename" -T' --The -S must be used with the -T
SET @Command = 'bcp '+@Statement+' '
EXEC master..xp_cmdshell @Command 
于 2017-04-06T15:21:05.837 回答