当我们执行以下命令时:
DBCC SHRINKFILE('MyDB_log', 1)
我们在 SSMS 中得到以下结果:
DBID | Field | CurrentSize | MinimumSize | UsedPages | Estimated Pages
-----|-------|-------------|-------------|-----------|----------------
11 | 2 | 128 | 128 | 128 | 128
问题:
我们如何在不使用 SSMS 输出窗口的情况下创建将这些结果输出到文本文件的查询。
我试过这个:
CREATE TABLE #x
(
[DBID] int,
FileID int,
CurrentSize int,
MinimumSize int,
UsedPages int,
EstimatedPages int
)
INSERT #x
EXEC('DBCC SHRINKFILE(''MyDB_log'', 1)')
SELECT *
FROM #x
DROP TABLE #x
但我收到以下错误:
Msg 8920, Level 16, State 2, Line 1
Cannot perform a shrinkfile operation inside a user transaction. Terminate the transaction and reissue the statement.
我还尝试了以下方法:
DECLARE @Statement AS VARCHAR(2000);
SET @Statement = 'bcp "DBCC SHRINKFILE(''MyDB_log'', 1)" queryout C:\Test.txt -c -UDBAdmin -P1234 -S192.168.123.123';
exec xp_cmdshell @Statement
我得到:
Error = [Microsoft][SQL Native Client]BCP host-files must contain at least one column
我看到的最简单的方法是使用 sqlcmd 的批处理文件:
重定向运算符在文件末尾附加数据。
-Q 参数用于立即关闭 sqlcmd 会话。
如果您正在查看一次性查询,则可以通过按 Ctrl+Shift+F 将查询结果输出到文件。
如果您正在寻找可以自动化的东西,您可以将查询包装在 Powershell 或其他脚本语言中并让其写入文件。
有两个足够简单的选项:使用链接服务器或 SQLCLR。
链接服务器
这个选项需要三件事:
将链接服务器的
'remote proc transaction promotion'
属性设置为false
,这可以防止 SQL Server 尝试使用 MSDTC 将本地和远程操作绑定到一个事务中。'rpc out'
链接服务器的属性,true
以便可以将返回的结果集DBCC
传回本地上下文。并且您通过以下方式使用链接服务器
EXEC('DBCC...') AT [LinkedServerName];
有关此方法的工作示例,请参阅我的回答(也在 DBA.SE 上):
如何将 DBCC SHRINKFILE 的结果保存到表中?
SQLCLR
Enlist
使用连接字符串关键字设置为的常规/外部连接(即不是上下文连接)false
,您可以创建 SQLCLR 存储过程或标量函数/UDF。就像'remote proc transaction promotion'
禁用了链接服务器一样,新连接Enlist = false;
不会尝试将本地和远程事务绑定在一起。虽然 UDF 确实更适合用于基于集合的操作,但最简单的方法(我相信,但尚未测试)是创建一个存储过程,在其中将
SqlCommand.ExecuteReader()
(SqlCommand
对象是对 的调用DBCC
)传递到SqlContext.Pipe.Send()
.