Frage

Ich bin mit ADO.NET SQL Server 2005 zugreifen und mag aus dem Innern der T-SQL gespeicherten Prozeduren protokollieren können, die ich rufe. Ist das irgendwie möglich?

Ich bin nicht in der Lage Ausgabe zu sehen von der ‚print'-Anweisung, wenn mithilfe von ADO.NET und da ich die Protokollierung für nur verwenden möge, würde die ideale Lösung debuging sein um Nachrichten zu Debugview von SysInternals zu emittieren.

War es hilfreich?

Lösung

Ich löste dies durch ein SQLCLR-Verfahren wie Eric Z Beard Schreiben vorgeschlagen. Die Montage muss mit einem starken Namen Schlüsseldatei signiert werden.

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;
        }
    }
}

Erstellt einen Schlüssel und ein Login:

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  

es in SQL Server importiert:

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

Dann konnte ich in T-SQL-Prozeduren zur Anmeldung mit

exec Debug @message = 'Hello World'

Andere Tipps

Ich denke, in einer Log-Tabelle zu schreiben wäre meine Präferenz.

Alternativ kann, wie Sie 2005 verwenden, können Sie eine einfache SQLCLR Prozedur schreiben, um den Event-Log zu wickeln.

Oder Sie könnten mit xp_logevent , wenn Sie SQL log

schreiben wollte

Sie können entweder melden Sie sich an einen Tisch, indem man einfach eine neue Zeile einzufügen, oder Sie können eine gespeicherte CLR-Prozedur implementieren, um eine Datei zu schreiben.

Seien Sie vorsichtig auf eine Tabelle mit dem Schreiben, weil, wenn die Aktion in einer Transaktion geschieht und die Transaktion zurückgesetzt wird, wird Sie Log-Eintrag verschwinden.

Protokollierung von innerhalb einer SQL sproc besser auf die Datenbank erfolgen würde selbst. T-SQL, um Dateien zu schreiben, aber es ist nicht wirklich für sie entworfen.

Es gibt die PRINT Befehl, aber ich ziehe in eine Tabelle anmelden, damit Sie es abfragen kann.

Sie können innerhalb einer gespeicherten Prozedur Zeilen in einer Log-Tabelle schreiben. Wie andere schon angedeutet haben, können Sie aus dem Weg gehen zu einem gewissen Textdatei oder ein anderes Protokoll mit CLR oder xp_logevent zu schreiben, aber es scheint, wie Sie mehr Volumen benötigen, als für solche Anwendungen praktisch sein würde.

Die harten Fälle auftreten (und es ist diese, die Sie wirklich Ihr Protokoll müssen), wenn Transaktionen scheitern. Da jede Protokollierung, die Rückseite wird zusammen mit der Transaktion rückgängig gemacht werden, während dieser Transaktionen erfolgt, dass sie Teil sind, ist es am besten, eine Logging-API zu haben, die Ihre Kunden verwenden können, um Fehler zu protokollieren. Dies kann eine einfache DAL, dass entweder Protokolle auf die gleiche Datenbank sein, oder in einem freigegebenen ein.

Für das, was es wert ist, die ich gefunden habe, dass, wenn ich zuweisen keinen Infomessage-Handler meine SqlConnection:

sqlConnection.InfoMessage += new SqlInfoMessageEventHandler(MySqlConnectionInfoMessageHandler);

, wo die Unterschrift des InfoMessageHandler sieht wie folgt aus:

MySqlConnectionInfoMessageHandler(object sender, SqlInfoMessageEventArgs e)

dann meine PRINT-Anweisungen in meiner Stored Procs erscheinen nicht in DbgView.

Sie könnten Ausgangsvariablen verwenden für Nachrichten vorbei zurück, aber das beruht auf der proc ohne Fehler ausgeführt wird.

create procedure usp_LoggableProc 

@log varchar(max) OUTPUT 

as

-- T-SQL statement here ...

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

Und dann in der ADO-Code somehwere:

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

Sie könnten raiserror verwenden, um Ihre eigenen Fehler mit den Informationen zu erstellen, die Sie benötigen, und das werden Sie durch die übliche SqlException Fehler Sammlung in Ihrem ADO-Code zur Verfügung:

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

Hmmm aber ja, kann nicht helfen, nur für das Debuggen fühlen und in Ihrer Situation, nur varchar Nachrichten an einen Fehler Tabelle einfügen wie die anderen vorgeschlagen haben, und wählen Sie * aus es, wenn Sie das Debuggen.

Sie können Log4TSQL überprüfen möchten. Es bietet Datenbank-Logging für Stored Procedures und Trigger in SQL Server 2005 -. 2008. Sie haben die Möglichkeit auf eine separate, unabhängige log-Stufen einstellen pro Prozedur / Trigger Basis

- Die folgende DDL SQL erstellen Sie die Tabelle, die die Protokolldaten zu speichern,    Verwenden Sie [db]     GO

/****** 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>      
*/  
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top