我正在使用 SQL Server 2016,我需要让用户从中MyDatabase
执行xp_cmdshell
。我执行以下操作:
USE [MyDatabase]
GO
GRANT EXECUTE ON xp_cmdshell TO myUser
GO
myUser
是来自的用户MyDatabase
,当我运行上述代码时,登录为sa
,我收到以下错误:
仅当当前数据库为主数据库时,才能授予对服务器范围目录视图或系统存储过程或扩展存储过程的权限。
我需要将用户添加到master
数据库吗?我不认为这是安全的。
我需要这个,因为我想从存储过程中编写一个文本文件。我找到了以下文章http://www.nigelrivett.net/WriteTextFile.html,说我可以使用以下方式编写文本文件:
You will need to create the data to be output as in dynamic sql statements
The first command here creates or overwrites the file - the rest append to the file.
exec master..xp_cmdshell 'echo hello > c:\file.txt'
exec master..xp_cmdshell 'echo appended data >> c:\file.txt'
exec master..xp_cmdshell 'echo more data >> c:\file.txt'
我问这个是因为我的存储过程会生成一个大字符串 (nvarchar(max)) json,当我尝试用 C# 写下它时,我什么也没得到:既不是文件也不是异常。我曾想过在存储过程中编写 json 字符串(如果可以的话)。
存储过程正确结束,我在调试器中检查了我在输出参数 json 中得到了一些东西(我知道是因为 Visual Studio 设置没有足够的内存来显示它的内容),File.WriteAllText
因为我有一个断点而运行它,而且,路径是绝对的。但也许,有些事情我忽略了,我必须再次仔细检查所有内容。
我建议您将执行 xp_cmdshell 的代码包装在用户数据库中的存储过程中,并使用具有所需权限的证书对其进行签名。这样,用户被限制在用户存储过程中,不能执行临时 xp_cmdshell 命令。操作系统权限也仅限于非系统管理员角色成员的代理帐户。此证书技术在Erland Sommarskog 的存储过程中的打包权限一文中有详细说明。
下面是一个示例脚本。
关于处理与执行相关的权限的问题
xp_cmdshell
,我同意(并赞成)丹的回答。但是,鉴于有关此请求原因的新信息(即写出大型 JSON 文档),安全性xp_cmdshell
成为一个有争议的问题,因为xp_cmdshell
最多只能处理 8000 个VARCHAR
字符(如果使用双字节字符集和其中的某些字符,则更少) ,但这里可能不是这种情况,只是需要注意)。另外,我似乎记得某些字符在命令行上效果不佳,并且不能轻易逃脱(但目前找不到)。所以也许最好接受 Dan 对这个问题的回答(因为它对于所述问题是正确的),然后打开一个关于如何最好地导出大型 JSON 文档的新问题,我可以将这个答案转移到那个问题.
File
通过使用该类的 SQLCLR,可以相当容易地处理此操作。请在 DBA.SE 上查看我的以下答案,其中包括一些用于执行此类操作的代码示例:
将结果导出到 XML
此外,对于不想弄乱编码、部署等的任何人:SQL#库(我编写的)中有一个File_Write函数可以处理这个问题,甚至允许传入所需的编码,以便文件可以例如,保存为带有字节顺序标记 (BOM) 的 UTF-8。请注意,此功能仅在完整版中可用,在免费版中不可用。这是一个相当简单的创建函数,但最好有选项。