MSSQL利用xp_cmdshell 写Debug Log程序

发布时间:2023年12月17日

用途

? ? ? 在写存储过程时,调试程序经常用PRINT或Table记录log,Table在事务提交在相对复杂,PRINT在查询分析器中有效,后端程序调用无法看到效果,针对此问题想到利用xp_cmdshell写Debug Log,以下代码供参考。

代码如下

Create PROC P_FILEOUTPUT
(	@PROC_NAME	sysname,
	@CODE  sysname,
	@EMS   sysname,
	@RET_MESSAGE VARCHAR(MAX) OUTPUT
)
AS

create table #t_output
(cmd varchar(100))

DECLARE @cmd varchar(4048),
		@db_name sysname,
		@path  sysname,
		@fileName sysname,
		@spid sysname ,
		@loginame varchar(10) ,
		@hostname  varchar(10),
		@program_name varchar(60) ,
		@cmd_txt  varchar(1024)   

	SET @db_name=DB_NAME()
	SET @path='d:\log\'+@db_name+'\'
    SET @fileName=@path+ISNULL(@PROC_NAME,'')+'_'+cast(@@SPID as varchar(20))+'.txt'
--如果文件夹不存在,需要建立
	SET @cmd = 'if not exist '+@path+' md '+@path
	INSERT INTO #t_output
	EXEC master..xp_cmdshell @cmd
--抓取进程记录
		SELECT   @spid = spid ,   
				  @loginame=  loginame  ,
				  @hostname=  hostname ,
				  @program_name=  program_name ,
				  @cmd_txt=cmd   
		FROM sys.sysprocesses
		WHERE spid = @@SPID
  
	   --如果该文件不存在,输入进程信息。便于查问题
		SET @cmd =  'if not exist '+@fileName+' '
		SET @cmd =@cmd+ '('+' '
		--SET @cmd =@cmd+'@echo off '
		SET @cmd =@cmd+ 'echo "%date%'+' '+'%time%"  >>'+@fileName+' '+char(13)
		SET @cmd =@cmd+'  '+ '"进程ID	|登录名		|主机名		|程序名		|命令" >>'+@fileName+' ' 
		SET @cmd =@cmd+'  "'+ ISNULL(@spid,'')+'|' + ISNULL(@loginame,'')+'|' + ISNULL(@hostname,'')+'|'  + ISNULL(@program_name,'')+'	|'+ ISNULL(@cmd_txt,'') +'" >>'+@fileName+' '
		SET @cmd =@cmd+') '
		--print @cmd
		INSERT INTO #t_output
		EXEC master..xp_cmdshell @cmd
		--分隔符
		IF  @CODE='*'
		BEGIN
			SET @cmd = 'echo "'+isnull(@EMS,'')+'" >>'+@fileName+' ' 
			-- print @cmd
			INSERT INTO #t_output
			EXEC master..xp_cmdshell @cmd
		END
		ELSE
		BEGIN

			--Log文件输出
			SET @cmd = 'echo "%date%'+' '+'%time%"  >>'+@fileName+' '
			SET @cmd =@cmd+'  "错误代码	|错误内容" >>'+@fileName+' '
			INSERT INTO #t_output
			EXEC master..xp_cmdshell @cmd

			SET @cmd = 'echo				"'+ISNULL(@CODE,'')+'		|'+isnull(@EMS,'')+'" >>'+@fileName+' ' 
			---print @cmd
			INSERT INTO #t_output
			EXEC master..xp_cmdshell @cmd
		END 
select @RET_MESSAGE=isnull(@RET_MESSAGE,'')+ cmd 
from #t_output where cmd is not null

--SELECT * FROM  #t_output


 


 

测试效果

测试语句

declare @RET_MESSAGE VARCHAR(MAX)
exec  P_FILEOUTPUT 	'程序名-自定义'	 ,	'1'   ,	'hu'  ,	@RET_MESSAGE OUTPUT
SELECT  @RET_MESSAGE

结果存在SET @path='d:\log\'+@db_name+'\' 相应的数据库下,文件名是参数@PROC_NAME+进程

文本内容:第一行为进程相关信息,可以根据自行需要调整【格式尝试多种方式未调整完善】

? ? ? ? ? ? ? ? ? 第二行为错误信息

分隔符使用? ? ? ??

在调整程序便于区分每段错误,经常使用分隔符,@CODE为*,@EMS为分隔符

 declare @RET_MESSAGE VARCHAR(MAX)
exec  P_FILEOUTPUT 	'程序名-自定义'	 ,	'*'   ,	'------------------------测试案例--------------------------------'  ,	@RET_MESSAGE OUTPUT
SELECT  @RET_MESSAGE

再次运行下面语句

declare @RET_MESSAGE VARCHAR(MAX)
exec  P_FILEOUTPUT 	'程序名-自定义'	 ,	'1'   ,	'测试效果2'  ,	@RET_MESSAGE OUTPUT
SELECT  @RET_MESSAGE

检查是否启用?xp_cmdshell

exec sp_configure 'xp_cmdshell';

#查看系统实例中是否有xp_cmdshell存储过程;

如果返回结果中的"run_value"为1,则表示xp_cmdshell已经启用

如果为0,则表示xp_cmdshell尚未启用。

启用?xp_cmdshell

-- 允许修改高级参数
exec sp_configure 'show advanced options',1;
-- 配置生效
RECONFIGURE;
-- 开启xp_cmdshell
exec sp_configure 'xp_cmdshell',1;
-- 配置生效
RECONFIGURE;

?运行结果信息如下:

关闭?xp_cmdshell

-- 开启高级选项 
exec sp_configure 'show advanced options',1;
-- 配置生效
RECONFIGURE;
-- 关闭xp_cmdshell
exec sp_configure 'xp_cmdshell',0;
-- 配置生效
RECONFIGURE;

检查是否存在?xp_cmdshell?存储过程

select *  from master.dbo.sysobjects where xtype='x' and name='xp_cmdshell';

恢复xp_cmdshell

存在?xplog70.dll?

exec master..xp_dropextendedproc xp_cmdshell,@dllname='xplog70.dll'

不存在?xplog70.dll?

exec master.dbo.sp_addextendedproc xp_cmdshell,@dllname='具体路径\xplog70.dll'

删除xp_cmdshell

exec master..sp_dropextendedproc xp_cmdshell;

官方说明:xp_cmdshell (Transact-SQL) - SQL Server | Microsoft Learn

文章来源:https://blog.csdn.net/sen_shan/article/details/134919888
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。