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