0

私は時々動作するコードのスライスを持っています。実行中のクエリは自分で作成したものではありませんが、データベースに対して実行するだけで必要な結果が得られると言われています。これが私のコードです:

try {
  using (SqlDataReader dr = cmd.ExecuteReader()) {
    while (dr.Read()) {
      try {
        list.Add(dr.GetString(3) + " " + dr.GetInt32(4).ToString() + " " + dr.GetString(5) + " " + dr.GetDecimal(8).ToString());
      } catch (Exception e) {
        list.Add("fail");
      }
    }
  }
} catch (SqlException sqlException) {
  Debug.WriteLine(sqlException.Message);
}

権限がないかテーブルが存在しないため、テーブルを削除できないというエラーが表示されることがあります。それ以外の場合、クエリは問題なく実行され、結果を取得してリストに保存できます。

SQL Server 2008 でクエリを実行すると、実際にエラーが発生することがありますが、結果は表示され、期待どおりです。だから私の質問は次のとおりです。いつでも発生するように見えるエラーに関係なく、これらの結果を取得するにはどうすればよいですか?

これは、私の問題を引き起こしているクエリの小さな部分です。

IF  EXISTS (SELECT * from tempdb..sysobjects where name like '#TABLE%')  
DROP #TABLE

私が実行しているクエリにはこれらのifステートメントが多数あり、どれがエラーを引き起こすかは予測できません。したがって、私が今行ったことは、DROP #TABLE を try-catch ブロックで囲み、少なくとも Silverlight プログラムで結果を取得できるようにすることです。上層部に連絡して、クエリがこれらのエラーを自発的に返す理由を尋ねます..

4

1 に答える 1

1

編集

気にしないでください、私は問題を見ます。異なるプロセス間の名前の競合を防ぐために、一時テーブル名に追加の文字が追加されることを忘れていました (例: #TABLE___...___0000000064E2)。

私の推測では、ストアド プロシージャは特定の状況下で「#TABLE」という名前の一時テーブルを作成しており、投稿した SQL コードの一部はクリーンアップを実行するためのものです。単独で実行する場合、これはおそらく問題なく動作します。

ストアド プロシージャが複数のクライアントによって同時に実行される場合、または前のクエリの 1 つがクリーンアップの実行に何らかの理由で失敗した場合 (おそらく途中でエラーが発生したため)、問題が具体化し始める可能性があります。このような状況では、誤検知が発生します (ストアド プロシージャはクリーンアップが必要であると判断しますが、実際には別のプロセスによって作成された一時テーブルが表示されます)。現在のプロセスに関連付けられた #TABLE がないため、エラーが発生します。

いずれにせよ、ステートメントを try-catch でラップすることは、適切なアプローチのように思えます。より良いアプローチには、コードのオーバーホールが含まれます。おそらく、クリーンアップが必要であることを示すために何らかのフラグを設定するか、共通テーブルと何らかのトランザクション キーを使用します (ドロップするのではなく、現在のトランザクションに関連付けられているすべてのレコードを削除します)。テーブル)。

一時テーブルの代わりにテーブル変数の使用を検討することもできます。

参照:
http://social.msdn.microsoft.com/Forums/en-US/sqltools/thread/02337dd5-5cfd-40d8-b529-12dc557d6a7e/

DROPまたは、次のステートメントを完全にスキップすることも検討してください
。Temporary Table Scope?


元の質問に答えるために、とにかく.NETアセンブリを介さずに、例外がスローされた後にSQLクエリから結果を取得する方法を知りません。SQL Server Management Studio は、苦労して習得して使用する価値のない、負荷の高いカスタムメイドの API を使用しています。


以下は無視して
ください(参照用に保存)

可能であれば、SQL クエリを次のように変更してみてください。

IF  EXISTS (SELECT * from tempdb..sysobjects where name = '#TABLE')
DROP #TABLE

like '#TABLE%'(に変更= '#TABLE')

このlikeステートメントは意味がありません... 「#TABLE」で始まるテーブルが他にあるかどうかは問題ではありません...正確に「#TABLE」という名前のテーブルがあるかどうかだけを知りたいとします。

私の推測では、これはロジックが変更されたケースの 1 つですが、おそらく 2 人の異なる人物によって途中で変更されたにすぎません。

于 2012-12-28T19:30:00.090 に答える