C# SQL监控与感叹

C# SQL监控与感叹,c#,sql,sql-server,entity-framework-4,extended-events,C#,Sql,Sql Server,Entity Framework 4,Extended Events,来自另一个线程,该线程向我提供了有关如何将监视添加到SQL Server的信息 这很有效,但我想更进一步。我希望能够在事务发生时将注释添加到日志中 不过,我希望能够将注释写入SQL日志中。比如,我可以做一个查询,然后调用Debugger.Logger.Write(“某种注释”),这样我就知道是什么了。我对SQL不太了解,所以我试图了解正在运行的是什么,以及在哪里运行 非常感谢您的帮助。我假设我必须运行另一个SQL查询才能将注释“插入”到查询流中 我设计我的数据上下文(DbContext) 然后

来自另一个线程,该线程向我提供了有关如何将监视添加到SQL Server的信息

这很有效,但我想更进一步。我希望能够在事务发生时将注释添加到日志中

不过,我希望能够将注释写入SQL日志中。比如,我可以做一个查询,然后调用Debugger.Logger.Write(“某种注释”),这样我就知道是什么了。我对SQL不太了解,所以我试图了解正在运行的是什么,以及在哪里运行

非常感谢您的帮助。我假设我必须运行另一个SQL查询才能将注释“插入”到查询流中

我设计我的数据上下文(DbContext)

然后调试器类

public static class Debugger
{
    public static System.IO.TextWriter File
    {
        get;
        set;
    }
    public static void Open()
    {
        // open a file for storing SQL results from queries
        File = new System.IO.StreamWriter("results.sql", false);
    }

    public static void Write(string text)
    {
        File.WriteLine(text);
    }

    public static bool Log(SampleDataContext context)
    {
        var results = context.Database.Connection.CreateCommand();
        results.CommandText = Sql.Review;
        context.Database.Connection.Open();

        System.Data.Common.DbDataReader resultsReader;
        do
        {
            resultsReader = results.ExecuteReader();
        }
        while (resultsReader == null);

        Console.WriteLine("Discovered a Data Reader");

        // Retrieves the schema of the table.
        var dtSchema = resultsReader.GetSchemaTable();

        string strRow; // represents a full row
        // Reads the rows one by one from the SqlDataReader
        // transfers them to a string with the given separator character and
        // writes it to the file.
        while (resultsReader.Read())
        {
            Console.WriteLine("Reading Data Reader... ");

            strRow = "";
            for (int i = 0; i < resultsReader.FieldCount; i++)
            {
                strRow += resultsReader.GetValue(i).ToString();
                if (i < resultsReader.FieldCount - 1)
                {
                    strRow += " ";
                }
            }

            Sql.Text.Lexer lexer = new Sql.Text.Lexer();
            lexer.Enscribe();

            var matches = lexer.Tokenize(strRow);
            matches.ForEach(x =>
                                {
                                    strRow = strRow.Replace(x.Value, Environment.NewLine);
                                });

            File.WriteLine(strRow);
        }

        File.Close();
        context.Database.Connection.Close();

        return false;
    }

    public static bool SetupLog(SampleDataContext context)
    {
        var command = context.Database.Connection.CreateCommand();
        command.CommandText = Sql.Record;

        context.Database.Connection.Open();
        command.ExecuteNonQuery();
        context.Database.Connection.Close();

        return true;
    }
}
然后我有另一个“Project.SQL.Review”

我的第一个想法是做一个这样的方法

    public static void WriteSql(SampleDataContext context, string text)
    {
        var command = context.Database.Connection.CreateCommand();
        command.Parameters.Add(new System.Data.SqlClient.SqlParameter("@Comment",System.Data.SqlDbType.VarChar));
        command.Parameters["@Comment"].Value = String.Format("--{0}", text);
        command.CommandText = String.Format("PRINT '{0}'", text.Replace("'", "''"));
        context.Database.Connection.Open();
        command.ExecuteNonQuery();
        context.Database.Connection.Close();
    }

它应该像查询一样执行注释,它应该显示在评论中,对吗?嗯,那没用。因此,我对其他想法持开放态度…

您可能需要使用
打印
语句来实现此目的。将参数化查询与名为
@Comment
的参数一起使用,然后执行

PRINT @Comment
如果需要轻松地将注释与常规查询区分开来,您可以添加一个新事件

,
ADD EVENT sqlserver.error_reported(
     ACTION (sqlserver.sql_text)
     WHERE (([severity]=(1))))  

并使用
RAISERROR(@Comment,1,1)

我编辑了代码的最后一部分以反映您的建议,但它只显示输出中的原始SQL“PRINT@Comment”。知道我哪里出错了吗?没有。也许可以尝试使用
varchar
而不是text作为参数<代码>文本
是LOB数据类型,因此可能无法使用打印。如果这不起作用,那么我想您可以使用类似于
command.CommandText=String.Format(“打印{0}',text.Replace(“,”)因为是您的代码创建注释,您不必担心SQL注入。我已经在上面的WriteSql方法中更新了我的代码,但仍然没有骰子。它不会在Sql输出中显示任何内容。
    public static void WriteSql(SampleDataContext context, string text)
    {
        var command = context.Database.Connection.CreateCommand();
        command.Parameters.Add(new System.Data.SqlClient.SqlParameter("@Comment",System.Data.SqlDbType.VarChar));
        command.Parameters["@Comment"].Value = String.Format("--{0}", text);
        command.CommandText = String.Format("PRINT '{0}'", text.Replace("'", "''"));
        context.Database.Connection.Open();
        command.ExecuteNonQuery();
        context.Database.Connection.Close();
    }
PRINT @Comment
,
ADD EVENT sqlserver.error_reported(
     ACTION (sqlserver.sql_text)
     WHERE (([severity]=(1))))