2

SQL クエリ (パラメーターは既に追加されています) を受け取り、データベースに対して実行する関数がいくつかあります。SQL クエリが失敗した場合、失敗の原因を正確に確認するために、パラメータを含めた完全なクエリをログに記録したいと考えています。query.ToString() は IBM.Data.Informix.IfxCommand を返すため、現在は query.CommandText をキャプチャしているだけですが、パラメーターが問題の原因である場合、これは私が何を扱っているかを正確に教えてくれません。

私が使用しているクエリ関数の1つを次に示します。

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 ループを作成して各パラメータを個別の項目として記録することです。これらのクエリの一部には多数のパラメーターがあり、1 つの簡単な文字列で完全なクエリを取得することはできないため、これは実際には最も理想的なソリューションではありません。

4

2 に答える 2

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 ステートメント:

catch (IBM.Data.Informix.IfxException ex)
{
  string errorQuery = RecreateQuery(query);
  LogError(ex, errorQuery);
  SendErrorEmail(ex, errorQuery);
  DisplayError();
}

このアプローチには、悪党の潜在的な問題がありますか? たとえば、ステートメントが設定しようとしている文字列に疑問符が含まれている場合などです。これは、このアプリケーションで使用しているデータでは非常にまれであり、上記のように疑問符をスペースで囲むことで、ユーザーが入力する非常にまれで奇妙な形式の文字列を除くすべてをカバーする必要があります.

于 2013-06-05T17:12:34.037 に答える