我有几个函数接受SQL查询(已添加参数)并对数据库运行它。当SQL查询失败时,我想记录完整的查询,包括参数,以便确切了解导致失败的原因。 query.ToString()返回IBM.Data.Informix.IfxCommand,所以目前我只是捕获query.CommandText,但是如果参数是导致问题的原因,那么这并不能告诉我我正在处理什么。
这是我正在使用的查询函数之一:
public DataTable CallDtQuery(IfxCommand query)
{
DataTable dt = new DataTable();
using (IBM.Data.Informix.IfxConnection conn = new IfxConnection(sqlConnection))
{
try
{
IBM.Data.Informix.IfxDataAdapter adapter = new IfxDataAdapter();
query.Connection = conn;
conn.Open();
adapter.SelectCommand = new IfxCommand("SET ISOLATION TO DIRTY READ", conn);
adapter.SelectCommand.ExecuteNonQuery(); //Tells the program to wait in case of a lock.
adapter.SelectCommand = query;
adapter.Fill(dt);
conn.Close();
adapter.Dispose();
}
catch (IBM.Data.Informix.IfxException ex)
{
LogError(ex, query.CommandText);
SendErrorEmail(ex, query.CommandText);
DisplayError();
}
}
return dt;
}
这是记录功能:
private void LogError(IfxException ex, string query)
{ //Logs the error.
string filename = HttpContext.Current.Server.MapPath("~") + "/Logs/sqlErrors.txt";
System.IO.FileStream fs = new System.IO.FileStream(filename, System.IO.FileMode.Append);
System.IO.StreamWriter sw = new System.IO.StreamWriter(fs);
sw.WriteLine("=======BEGIN ERROR LOG=======");
sw.WriteLine(DateTime.Now.ToShortDateString() + " " + DateTime.Now.ToLongTimeString());
sw.WriteLine("Query = " + query);
sw.WriteLine("User = " + HttpContext.Current.Session["UserID"]);
sw.WriteLine("Error Message = " + ex.Message);
sw.WriteLine("Message Source:");
sw.WriteLine(ex.Source);
sw.WriteLine("=============================");
sw.WriteLine("Message Target:");
sw.WriteLine(ex.TargetSite);
sw.WriteLine("=============================");
sw.WriteLine("Stack Trace:");
sw.WriteLine(ex.StackTrace);
sw.WriteLine("========END ERROR LOG========");
sw.WriteLine("");
sw.Close();
fs.Close();
}
有没有办法传递整个字符串,包括参数,用于记录,就像我在这里一样?我发现应该工作的唯一方法是将查询传递给日志记录函数并构建for循环以将每个参数记录为单独的项目。由于其中一些查询具有许多参数,并且由于我没有在一个简单的字符串中获得完整的查询,因此这不是最理想的解决方案。
答案 0 :(得分:3)
怎么样:
// ...
catch (IBM.Data.Informix.IfxException ex)
{
LogError(ex, query); // NOTE
SendErrorEmail(ex, query.CommandText);
DisplayError();
}
并创建一个像这样的重载:
private void LogError(IfxException ex, IfxCommand query)
{
StringBuilder sb = new StringBuilder();
sb.Append(String.Format("{0}\n", query.CommandText));
foreach (IDataParameter parameter in query.Parameters)
sb.Append(String.Format("\t{0} = {1}\n",
parameter.ParameterName, parameter.Value));
LogError(ex, sb.ToString());
}
答案 1 :(得分:0)
鲁本斯:
由于我想将查询传递给LogError和SendErrorEmail函数,因此我为此方法创建了一个独特的函数。我还调整了您的版本以自动替换参数点(例如,查询中的“cmt_slmno =?”),而不是制作参数列表。结果如下:
private string RecreateQuery(IfxCommand query)
{
StringBuilder sb = new StringBuilder();
sb.Append(query.CommandText);
foreach (IfxParameter parameter in query.Parameters)
sb.Replace(" ? ", string.Format(" {0} ", parameter.Value.ToString()));
return sb.ToString();
}
相应调整的捕获声明:
catch (IBM.Data.Informix.IfxException ex)
{
string errorQuery = RecreateQuery(query);
LogError(ex, errorQuery);
SendErrorEmail(ex, errorQuery);
DisplayError();
}
这种方法有潜在的流氓问题吗?在文本中被替换,例如,如果语句在其尝试设置的字符串中有一个问号。对于我在这个应用程序中使用的数据,这应该是非常罕见的,并且上面带有空格的问号应该覆盖用户放入的极其罕见的,奇怪格式化的字符串。