2

このレガシー コードは、アプリ内の無数の場所から呼び出されます。

    public void DBCommand(string dynSQL, bool Silent)
    {
        checkConnection();
        SqlCeCommand cmd = objCon.CreateCommand();
        SqlCeTransaction trans = this.GetConnection().BeginTransaction();
        cmd.Transaction = trans;

        try
        {
            cmd.CommandText = dynSQL;
            cmd.ExecuteNonQuery();
            trans.Commit();
        }
        catch (Exception ex)
        {
            MessageBox.Show(
                string.Format("DBCommand Except in DBConnection.DBCommand: {0}. InnerException: {1}", ex.Message, ex.InnerException));//TODO: Remove
            try 
            {
                trans.Rollback();
            }
            catch (SqlCeException) 
            {
                // Handle possible exception here
            }
//              MessageBox.Show(
//                  string.Format("DBCommand Except in DBConnection.DBCommand: {0}. InnerException: {1}", ex.Message, ex.InnerException));//TODO: Remove
                WriteDBCommandException(dynSQL, ex, Silent);
            }
        }

特定のファイルがロードされ、その内容がデータベースに挿入されると、このメッセージが 5 回表示されます。ただし、例外の Message と InnerException は常に空の文字列です。

私も(おそらく迷信的または非論理的に)MessageBox.Show()をある場所から別の場所に移動して、違いが生じるかどうかを確認しました(違いはありません)。

例外が表示されますが、問題の内容に関する有用な情報は提供されません。問題のデータを (手動で、より正確には、文字通り光学的にスキャンしたと思います) 調べましたが、すべて問題ないようです。

では、なぜこの例外メッセージは泣いたり嘆いたりしているのに、疝痛はあるが無言の赤ちゃんのように (口を大きく開けて、涙が流れ落ちているが、音は漏れていない)、問題が何であるかを伝えていないのでしょうか?

アップデート

さて、私は ErikEJ のコード スニペットを適合させました (私はずっと昔、Alley Oop、Bertha Butt、Artie Shaw の時代のツールを使用しているため、HelpLink または StringIsNullOrEmpty を使用できませんでした):

            // from method that throws the exception
            catch (SqlCeException sqlfail)
            {
                MessageBox.Show(GetSQLCEErrorInfo(sqlfail));
            }
            catch (Exception ex)
. . .

        public static string GetSQLCEErrorInfo(SqlCeException args)
        {
            SqlCeErrorCollection errorCollection = args.Errors;

            StringBuilder bld = new StringBuilder();
            Exception inner = args.InnerException;

            if (null != inner)
            {
                bld.Append("\nInner Exception: " + inner.ToString());
            }
            // Enumerate the errors to a message box.
            foreach (SqlCeError err in errorCollection)
            {
                bld.Append("\n Error Code: " + err.HResult.ToString("X", 
System.Globalization.CultureInfo.InvariantCulture));
                bld.Append("\n Message   : " + err.Message);
                bld.Append("\n Minor Err.: " + err.NativeError);
                bld.Append("\n Source    : " + err.Source);
                // Enumerate each numeric parameter for the error.
                foreach (int numPar in err.NumericErrorParameters)
                {
                    if (0 != numPar) bld.Append("\n Num. Par. : " + numPar);
                }
                // Enumerate each string parameter for the error.
                foreach (string errPar in err.ErrorParameters)
                {
                    if ((null != errPar) && (errPar.Trim() != string.Empty))  //IsNullOrEmpty(errPar))
                    {
                        bld.Append("\n Err. Par. : " + errPar);
                    }
                }
            }
            return bld.ToString();
        }

...そして、次のように表示されます。

Error Code: 80040E14
Message : There was an error parsing the query. [Token line number, Token line offset,, Token in error,,]
Minor Err.: 25501
Source : Microsoft SQL Server 2000 Windows CE Edition
Num. Par. : 1
Num. Par. : 47
Err. Par. " [

...それから:

Exception: SLQ Server CE does not support parallel transactions.
Location. DBConnection.GetInstance(siteNo)

(私はそれらの両方を2回取得します); しかし、なぜ2回だけですか?数百のレコードを挿入します...一度失敗すると、毎回失敗すると思うでしょう。

4

1 に答える 1

3

あなたは間違っています。一般的な例外をキャッチする前に、ExecuteNonQuery によって引き起こされるより特殊な SqlCeException をキャッチする必要があります。また、SqlCeExcpetion の場合、特別な処理が必要です。次のようなものを使用して、関連するすべての情報を取得できます。

public static string ShowErrors(System.Data.SqlServerCe.SqlCeException e)
{
System.Data.SqlServerCe.SqlCeErrorCollection errorCollection = e.Errors;

StringBuilder bld = new StringBuilder();
Exception inner = e.InnerException;

if (!string.IsNullOrEmpty(e.HelpLink))
{
    bld.Append("\nCommand text: ");
    bld.Append(e.HelpLink);
}

if (null != inner)
{
    bld.Append("\nInner Exception: " + inner.ToString());
}
// Enumerate the errors to a message box.
foreach (System.Data.SqlServerCe.SqlCeError err in errorCollection)
{
    bld.Append("\n Error Code: " + err.HResult.ToString("X", System.Globalization.CultureInfo.InvariantCulture));
    bld.Append("\n Message   : " + err.Message);
    bld.Append("\n Minor Err.: " + err.NativeError);
    bld.Append("\n Source    : " + err.Source);

    // Enumerate each numeric parameter for the error.
    foreach (int numPar in err.NumericErrorParameters)
    {
        if (0 != numPar) bld.Append("\n Num. Par. : " + numPar);
    }

    // Enumerate each string parameter for the error.
    foreach (string errPar in err.ErrorParameters)
    {
        if (!string.IsNullOrEmpty(errPar)) bld.Append("\n Err. Par. : " + errPar);
    }
  }
  return bld.ToString();
}
于 2013-06-04T17:17:39.450 に答える