ADO.NET을 사용하여 SQL Server 2005에 액세스하고 있으며 내가 호출하는 T-SQL 저장 프로 시저 내부에서 로그온 할 수 있기를 원합니다. 어떻게 든 가능합니까?T-SQL에 로그인하는 방법
ADO.NET을 사용할 때 'print'-statement의 결과를 볼 수 없으며 이상적인 솔루션을 디버깅하기위한 로깅을 사용하고자하므로 SysInternals에서 DebugView로 메시지를 보내야합니다.
ADO.NET을 사용하여 SQL Server 2005에 액세스하고 있으며 내가 호출하는 T-SQL 저장 프로 시저 내부에서 로그온 할 수 있기를 원합니다. 어떻게 든 가능합니까?T-SQL에 로그인하는 방법
ADO.NET을 사용할 때 'print'-statement의 결과를 볼 수 없으며 이상적인 솔루션을 디버깅하기위한 로깅을 사용하고자하므로 SysInternals에서 DebugView로 메시지를 보내야합니다.
GO 당신에게 로그 데이터 사용을 저장하는 테이블을 생성합니다.어셈블리는 강력한 이름의 키 파일로 서명되어야합니다.
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;
}
}
}
는 키와 로그인을 만든 :
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 절차에 로그인 할 수 있었다
exec Debug @message = 'Hello World'
를 사용하여 :
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 서버로를 수입
새 행을 삽입하기 만하면 테이블에 로그온하거나 CLR 저장 프로 시저를 구현하여 파일에 쓸 수 있습니다.
조치가 트랜잭션에서 발생하고 트랜잭션이 롤백되면 로그 항목이 사라 지므로 테이블에 기록하는 데주의하십시오.
로깅이 사라지는 문제를 방지하기 위해 로그 엔트리를 테이블 변수에 기록한 다음 트랜잭션이 커밋되거나 롤백 된 후 테이블 변수 데이터를 로그 테이블에 삽입합니다 . – HLGEM
SQL sproc 내부에서 로깅하는 것이 데이터베이스 자체를 더 잘 수행 할 수 있습니다. T-SQL은 파일에 쓸 수는 있지만 실제로 설계된 것은 아닙니다.
나는 로그 테이블에 글을 쓰는 것이 나의 취향이라고 생각한다.
또는 2005를 사용하는 경우 간단한 SQLCLR 프로 시저를 작성하여 EventLog를 랩핑 할 수 있습니다.
아니면 SQL 로그
PRINT 명령 거기에 기록하기를 원한다면 당신은 xp_logevent를 사용할 수 있지만 당신이 그것을 쿼리 할 수 있도록 나는 테이블에 로그인 선호합니다.
메시지를 되돌리기 위해 출력 변수를 사용할 수 있지만 오류없이 실행중인 proc를 사용합니다.
create procedure usp_LoggableProc
@log varchar(max) OUTPUT
as
-- T-SQL statement here ...
select @log = @log + 'X is foo'
그리고 somehwere 당신의 ADO 코드 :
string log = (string)SqlCommand.Parameters["@log"].Value;
당신은 당신이 필요로 해, 평소의 SQLException 오류를 통해 당신에게 사용할 수있는 정보와 사용자 정의 오류를 만들 RAISERROR를 사용할 수 있습니다 당신의 ADO 코드의 컬렉션 :
RAISERROR('X is Foo', 10, 1)
흠하지만, 그래, 그냥 오류로 VARCHAR 메시지를 삽입 단지 디버깅 및 상황에 기분이 도움이되지 수 다른 사람들과 같이 테이블은 당신이 디버깅 할 때 제안하고 * 선택합니다.
저장 프로 시저 내에서 로그 테이블에 행을 쓸 수 있습니다. 다른 사람들이 지적했듯이, CLR이나 xp_logevent를 사용하여 텍스트 파일이나 다른 로그에 쓸 수는 있지만, 그러한 용도로 사용하는 것보다 더 많은 볼륨이 필요합니다.
트랜잭션이 실패 할 때 까다로운 경우가 발생합니다 (로그가 필요합니다). 이러한 트랜잭션 중에 발생하는 모든 로깅은 트랜잭션의 일부로 롤백되므로 클라이언트가 오류를 로그하는 데 사용할 수있는 로깅 API를 갖는 것이 가장 좋습니다. 이것은 동일한 데이터베이스 또는 공유 데이터베이스에 기록하는 간단한 DAL 일 수 있습니다.
- 다음 DDL의 SQL은 [DB] 내가 에릭 Z 수염 제안으로 SQLCLR-절차를 작성하여이 문제를 해결
/****** 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>
*/
무엇 때문에 t의 가치는, 내가 발견 한 그 내도록 SqlConnection에 InfoMessage 핸들러를 지정하지 않는 경우 : 다음
MySqlConnectionInfoMessageHandler(object sender, SqlInfoMessageEventArgs e)
다음 InfoMessageHandler의 서명은 다음과 같습니다
sqlConnection.InfoMessage += new SqlInfoMessageEventHandler(MySqlConnectionInfoMessageHandler);
내 저장된 Procs 내 내 PRINT 문을 DbgView 나타나지 않습니다.
이것은 많은 부분에있어서 가장 좋은 답입니다. – Contango
Log4TSQL을 확인하실 수 있습니다. SQL Server 2005 - 2008에서 저장 프로 시저 및 트리거에 대한 데이터베이스 로깅을 제공합니다. 프로 시저/트리거별로 별도의 독립적 인 로그 수준을 설정할 수 있습니다.
뒤에 사용 된 아키텍처는 무엇입니까? 롤백 중 LOG4SQL이 로그 데이터를 저장하는 방법은 무엇입니까? –
로그인 하시겠습니까? – Josef
정보를 디버깅하는 것만으로 "X is Foo" –