如何在SQL Server每次执行时将存储过程结果存入独立新文本文件
解决每次执行生成新日志文件的问题
我懂你的痛点——原来的脚本每次都往同一个out.txt里追加内容,你想要的是每次运行都生成一个全新的独立文件,完全不碰旧文件对吧?
问题出在你固定了文件名C:\Tmp\log\out.txt,不管用>>还是>,只要文件名不变,要么追加要么覆盖。要生成新文件,核心思路就是让每次执行的文件名都不一样,最常用的办法就是给文件名加上时间戳(精确到秒甚至毫秒),这样几乎不可能重复。
修改后的代码示例
-- 生成带时间戳的唯一文件名,替换Windows不允许的冒号为下划线 Declare @fn varchar(8000) = 'C:\Tmp\log\out_' + REPLACE(REPLACE(CONVERT(varchar(19), GETDATE(), 120), '-', '_'), ':', '_') + '.txt'; Declare @cmd varchar(8000); DECLARE @viewObjectIds TABLE (object_id INT); INSERT INTO @viewObjectIds SELECT o.object_id FROM sys.objects AS o WHERE o.type = 'V'; DECLARE view_cursor CURSOR FAST_FORWARD FOR SELECT object_id FROM @viewObjectIds; OPEN view_cursor; FETCH NEXT FROM view_cursor INTO @object_id; WHILE @@FETCH_STATUS = 0 BEGIN DECLARE @command varchar(8000); -- 补充声明变量,避免未定义报错 SELECT @command = 'EXECUTE sp_refreshview ''' + QUOTENAME(OBJECT_SCHEMA_NAME(@object_id)) + '.' + QUOTENAME(OBJECT_NAME(@object_id)) + ''';'; PRINT @command; -- 新文件直接用>写入即可,不需要追加符号>> SELECT @cmd = 'echo '+ @command + ' > '+ @fn + '' ; exec xp_cmdshell @cmd FETCH NEXT FROM view_cursor INTO @object_id; END CLOSE view_cursor; -- 关闭游标释放资源 DEALLOCATE view_cursor;
关键说明
唯一文件名生成逻辑:
- 用
GETDATE()获取当前时间,通过CONVERT(varchar(19), GETDATE(), 120)转成yyyy-mm-dd hh:mi:ss格式的字符串 - 用
REPLACE把字符串里的-和:替换成_(Windows文件名不允许出现冒号) - 最终生成的文件名类似
out_2024_05_20_14_35_42.txt,每次执行时间不同,文件名就完全唯一
- 用
写入方式调整:
因为是全新文件,用>直接写入即可,不需要>>追加(如果同一个新文件里要写入多行内容,还是可以用>>,但这里我们每次都是独立新文件,>更直接)游标资源清理:
原代码遗漏了关闭和释放游标操作,补充后可以避免数据库资源泄漏
这样修改后,你每次执行这个脚本,都会在C:\Tmp\log\目录下生成一个带时间戳的新日志文件,完全不会影响之前生成的旧文件~
内容的提问来源于stack exchange,提问作者satcha
相关产品推荐
相关产品推荐

