关于sql server:如何登录T-SQL

关于sql server:如何登录T-SQL

How to log in T-SQL

我正在使用ADO.NET来访问SQL Server 2005,并且希望能够从我正在调用的T-SQL存储过程中进行记录。 有可能吗?

使用ADO.NET时,我看不到'print'语句的输出,因为我只想使用日志记录进行调试,所以理想的解决方案是从SysInternals向DebugView发出消息。


我通过按照Eric Z Beard的建议编写一个SQLCLR过程来解决此问题。程序集必须使用强名称密钥文件签名。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
using System;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;

public partial class StoredProcedures
{
    [Microsoft.SqlServer.Server.SqlProcedure]
    public static int Debug(string s)
    {
        System.Diagnostics.Debug.WriteLine(s);
            return 0;
        }
    }
}

创建了一个密钥和一个登录名:

1
2
3
4
5
6
7
USE [master]
CREATE ASYMMETRIC KEY DebugProcKey FROM EXECUTABLE FILE =
'C:\..\SqlServerProject1\bin\Debug\SqlServerProject1.dll'

CREATE LOGIN DebugProcLogin FROM ASYMMETRIC KEY DebugProcKey

GRANT UNSAFE ASSEMBLY TO DebugProcLogin

将其导入到SQL Server:

1
2
3
4
5
6
7
8
USE [mydb]
CREATE ASSEMBLY SqlServerProject1 FROM
'C:\..\SqlServerProject1\bin\Debug\SqlServerProject1.dll'
WITH PERMISSION_SET = unsafe

CREATE FUNCTION dbo.Debug( @message as nvarchar(200) )
RETURNS int
AS EXTERNAL NAME SqlServerProject1.[StoredProcedures].Debug

然后,我能够使用以下命令登录T-SQL过程

1
exec Debug @message = 'Hello World'

我认为写日志表是我的偏爱。

另外,在使用2005时,您可以编写一个简单的SQLCLR过程来包装EventLog。

或者,如果您想写入SQL日志,则可以使用xp_logevent


从SQL sproc内部进行记录最好对数据库本身进行记录。 T-SQL可以写入文件,但并不是真正为它设计的。


您可以通过简单地插入新行来登录到表,也可以实现CLR存储过程来写入文件。

写入表时要小心,因为如果操作在事务中发生并且该事务被回滚,则您的日志条目将消失。


有PRINT命令,但我更喜欢登录表以便查询。


对于它的价值,我发现当我没有为我的SqlConnection分配InfoMessage处理程序时:

1
sqlConnection.InfoMessage += new SqlInfoMessageEventHandler(MySqlConnectionInfoMessageHandler);

InfoMessageHandler的签名如下所示:

1
MySqlConnectionInfoMessageHandler(object sender, SqlInfoMessageEventArgs e)

那么我的存储过程中的PRINT语句就不会出现在DbgView中。


您可以从存储过程中将行写入日志表。正如其他人所指出的那样,您可以使用CLR或xp_logevent来写一些文本文件或其他日志,但是似乎您需要的容量超出了实际使用的容量。

当事务失败时,就会出现棘手的情况(这正是您真正需要的日志)。由于在这些事务期间发生的任何日志记录都会与它们所属的事务一起回滚,因此最好拥有一个日志API,您的客户端可以使用该API记录错误。这可以是一个简单的DAL,可以记录到同一数据库或共享的DAL中。


您可能要检查Log4TSQL。它提供了SQL Server 2005-2008中存储过程和触发器的数据库日志记录。您可以在每个过程/触发器的基础上设置单独的独立日志级别。


您可以使用输出变量来传递消息,但这依赖于proc执行而没有错误。

1
2
3
4
5
6
7
8
9
create procedure usp_LoggableProc

@log varchar(max) OUTPUT

as

-- T-SQL statement here ...

select @log = @log + 'X is foo'

然后在您的ADO代码中:

1
string log = (string)SqlCommand.Parameters["@log"].Value;

您可以使用raiserror来创建自己的自定义错误,以及所需的信息,这些信息可以通过ADO代码中的常规SqlException Errors集合提供给您:

1
RAISERROR('X is Foo', 10, 1)

嗯,但是,是的,不禁感到自己只是调试而已,在您所处的情况下,只需将varchar消息插入错误表中即可,就像其他人建议的那样,并在调试时从中选择*。


-以下DDL sql将创建表以存储日志数据
使用[db]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
/****** Object:  Table [dbo].[tbData_Debug]    Script Date: 02/12/2009 22:30:03 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

SET ANSI_PADDING ON
GO

CREATE TABLE [dbo].[tbData_Debug](
    [colTimeStamp] [timestamp] NULL,
    [colNiceTime] [varchar](200) NULL,
    [colDomain_User] [varchar](200) NULL,
    [colMsg] [varchar](4000) NULL,
    [colDebugLevel] [int] NULL,
    [colDebugMsg] [varchar](4000) NULL,
    [colPageName] [varchar](200) NULL,
    [colClassName] [varchar](200) NULL,
    [colMethodName] [varchar](200) NULL,
    [colMethodNameGui] [varchar](4000) NULL,
    [colRet] [int] NULL,
    [colLineNumber] [int] NULL,
    [colLineNumberGui] [int] NULL,
    [colProcedureName] [varchar](200) NULL,
    [colProcedureStep] [varchar](4000) NULL
) ON [PRIMARY]

GO

SET ANSI_PADDING OFF
GO




-- This stored procedure does write to the log table

USE [db]
GO
/****** Object:  StoredProcedure [dbo].[procUtils_AppDebug]    Script Date: 02/12/2009 22:29:24 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE [dbo].[procUtils_AppDebug] (                  

@ret int = null OUT,    
@msgIn varchar(4000) = null ,   -- the msg which the user has seen  
@msgOut varchar(4000) = null OUT ,   -- the msg which the user has seen  
@domain_user varchar(200) = null ,                 -- the domain user echoing the message  
@debugMsgIn varchar(4000) = null  ,   -- the debug msg for internal use  
@debugMsgOut varchar(4000) = null  OUT,   -- the debug msg for internal use  
@pageName varchar(200) = null ,   -- the pageName originator of error  
@className varchar(200) = null ,   -- the class Name orinator of error  
@methodName varchar(200) = null ,   -- the methodName where the last error occured  
@methodNameGui varchar(4000) = null ,   -- the methodNameOfTheGui where the last error occured  
@lineNumber int = null ,  -- the line number of the line issueing the error  
@lineNumberGui int = null,   -- the line number of the line issueing the error              
@procedureName varchar(200) = null , -- the procedureName currently envoked
@procedureStep varchar(4000)  = null -- the steps of the procedure concatenated
)    

AS                  
BEGIN -- proc start                
 SET NOCOUNT ON;                

BEGIN TRY        --begin try      

declare @debugLevel int    
select @debugLevel =  Debug_Level from User_tb where Domain_Name = @domain_user  

/*                  
select * from tbData_Debug    order by 1 desc              
delete from tbData_Debug              
*/
   


insert into tbData_Debug ( colNiceTime , colDomain_User , colMsg , colDebugLevel ,  
colDebugMsg , colPageName , colClassName , colMethodName , colMethodNameGui ,  
colRet , colLineNumber , colLineNumberGui , colProcedureName , colProcedureStep) values (
 dbo.funcGetNiceTime() , @domain_user  , @msgIn , @debugLevel ,@debugMsgIn ,
 @pageName , @className , @methodName  ,@MethodNameGui , @ret ,
 @lineNumber , @lineNumberGui , @procedureName , @procedureStep)    

set @debugMsgOut = @debugMsgIn  
set @msgOut = 'Action Registered'  
set @ret = @@ERROR    
return @ret                



END TRY        --end try      

BEGIN CATCH            
 PRINT 'In CATCH block.            
 Error number: '
+ CAST(ERROR_NUMBER() AS varchar(10)) + '            
 Error message: '
+ ERROR_MESSAGE() + '            
 Error severity: '
+ CAST(ERROR_SEVERITY() AS varchar(10)) + '            
 Error state: '
+ CAST(ERROR_STATE() AS varchar(10)) + '            
 XACT_STATE: '
+ CAST(XACT_STATE() AS varchar(10));            

 set  @debugMsgOut = 'error at [procUtils_AppDebug]--- Error number: ' + CAST(ERROR_NUMBER() AS varchar(10)) + 'Error message: ' + ERROR_MESSAGE() + 'Error severity: ' +  
CAST(ERROR_SEVERITY() AS varchar(10)) + 'Error state: ' + CAST(ERROR_STATE() AS varchar(10)) + 'XACT_STATE: ' + CAST(XACT_STATE() AS varchar(10))            
set @msgIn= 'error while saving application error info into database'  
insert into tbData_Debug ( colMsg ) values ( @msgIn )    

set @debugMsgOut = @debugMsgIn +  @debugMsgOut  
set @msgOut = 'Action Registration failed'  
set @ret = 1          

END CATCH            


return  @ret                      
END --procedure end                

/*      
<procedureDocumentation>      

<procedurename>procUtils_AppDebug<procedurename>      
<procedureDescription> Records events from the Application Layer </procedureDescription>    
<created>20090121</created>      
<createdby>Yordan Georgiev</createdby>      
<change>      

<changewhen><changewhen>      
<changeDescription></changeDescription>      
<changedBy></changedBy>      
</change>      


<testUsage>    

USE [db]    
GO    

DECLARE @return_value int,    
  @ret int,    
  @msgIn varchar(max),    
  @debugmsg varchar(4000)    

SELECT @ret = 1    
SELECT @msgIn = N'msg'    
SELECT @debugmsg = N'before'    

EXEC @return_value = [dbo].[procUtils_AppDebug]    
  @ret = @ret OUTPUT,    
  @msgIn = @msgIn OUTPUT,    
  @domain_user = N'domain_user',    
  @debugmsg = @debugmsg OUTPUT,    

  @methodName = N'methodName'    

SELECT @ret as N'@ret',    
  @msgIn as N'@msgIn',    
  @debugmsg as N'@debugmsg'    

SELECT 'Return Value' = @return_value    
select * from tbData_Debug order by 1 desc    
GO    

</testUsage>      
</procedureDocumentation>      
*/


推荐阅读

    linux常用输出命令?

    linux常用输出命令?,工作,系统,地址,管理,信息,标准,命令,目录,数据,位置,lin

    linux外部命令调用?

    linux外部命令调用?,系统,软件,标准,命令,盘中,管理,外部,进程,程序,内存,lin

    linux登录系统的命令?

    linux登录系统的命令?,系统,工作,地址,名称,网络,密码,信息,服务,软件,资料,l

    linux怎么调用命令行?

    linux怎么调用命令行?,系统,地址,工具,工作,首页,终端,命令,密码,信息,情况,l

    linux声音输出命令?

    linux声音输出命令?,电脑,系统,设备,服务,软件,数据,工具,情况,手机,命令,lin

    浏览器调用linux命令?

    浏览器调用linux命令?,系统,信息,人工智能,软件,数据,首次,地址,代码,咨询,

    py调用linux的命令?

    py调用linux的命令?,系统,代码,状态,环境,标准,工具,命令,文件,脚本,终端,lin

    浏览器调用linux命令?

    浏览器调用linux命令?,系统,信息,人工智能,软件,数据,首次,地址,代码,咨询,

    用linux命令输出id?

    用linux命令输出id?,系统,设备,工作,信息,地址,命令,工具,基础,目录,进程,lin

    py调用linux的命令?

    py调用linux的命令?,系统,代码,状态,环境,标准,工具,命令,文件,脚本,终端,lin

    linux命令输出太多?

    linux命令输出太多?,命令,标准,信息,时间,名称,文件,内容,屏幕,模式,目录,lin

    linux系统命令调用?

    linux系统命令调用?,系统,单位,工具,工作,管理,地址,权威,密码,电脑,信息,怎

    linux调用上一条命令?

    linux调用上一条命令?,系统,命令,一致,数字,名称,网上,电脑,目录,空格,终端,l

    linux用户登录的命令?

    linux用户登录的命令?,系统,信息,工作,地址,时间,密码,名称,命令,电脑,软件,l

    linux命令行调用程序?

    linux命令行调用程序?,工具,环境,代码,初级,工程,系统,网上,服务,管理,发行,l

    linux命令输出截图?

    linux命令输出截图?,工具,图片,代码,截图,环境,支柱,网络,标准,发展,命令,Lin

    linux命令行调试代码?

    linux命令行调试代码?,环境,代码,信息,平台,程序,编辑,版本,步骤,体系结构,

    linux下单步调试命令?

    linux下单步调试命令?,信息,系统,代码,工程,地址,工具,工作,数据,管理,环境,l

    linux系统输出命令?

    linux系统输出命令?,系统,工作,地址,信息,命令,工具,目录,设备,基础,发行,lin

    linux串口调试命令?

    linux串口调试命令?,设备,数据,信息,数字,系统,标准,通讯,软件,通用,状态,lin