2012-04-17 10 views
1

1-テーブルに列を追加するためのコマンドを実行 エラー選択欄は最近

2- Oracle.DataAccess

を使用してOracle XEに接続ODP.NETのALTER TABLEが挿入します;

3- DataReaderオブジェクトを使用してこのコラム

、4-読み取りを選択するためのコマンドを実行します。アプリケーションは、IndexOutOfRangeExceptionが発生します。その結果で指定した列を見つけることができません

を設定し、5-、アプリケーションを再起動し、DataReaderのは、私が今作成した列にアクセスすることができないのはなぜクエリが正しく

を実行しますか?あなたがリーダーを実行すると、挿入トランザクションがまだコミットされていないようですね

private void button1_Click(object sender, EventArgs e) 
{ 
    using (OracleConnection con = new OracleConnection(Settings.Default.CS)) 
    { 
     con.Open(); 
     try 
     { 
      using (OracleCommand com = new OracleCommand()) 
      { 
       com.Connection = con; 

       // Create a test table 
       com.CommandText = "CREATE TABLE Test (a int)"; 
       com.ExecuteNonQuery(); 

       // Add one column 
       com.CommandText = "ALTER TABLE Test ADD b int"; 
       com.ExecuteNonQuery(); 

       com.CommandText = "SELECT * FROM Test"; 
       using (DbDataReader dr = com.ExecuteReader()) 
       { 
        MessageBox.Show(dr.FieldCount.ToString()); 
        // Here is showing "2", thats ok 
       } 
      } 
     } 
     finally 
     { 
      con.Close(); 
     } 
    } 
} 

private void button2_Click(object sender, EventArgs e) 
{ 
    using (OracleConnection con = new OracleConnection(Settings.Default.CS)) 
    { 
     con.Open(); 
     try 
     { 
      using (OracleCommand com = new OracleCommand()) 
      { 
       OracleTransaction trans = con.BeginTransaction(); 
       try 
       { 
        // Add a column to table already created 
        com.Connection = con; 
        com.CommandText = "ALTER TABLE Test ADD c int"; 
        com.ExecuteNonQuery(); 

        // Insert a value, ok 
        com.CommandText = "INSERT INTO TEST (a, b, c) VALUES (1, 2, 3)"; 
        com.ExecuteNonQuery(); 

        trans.Commit(); 
       } 
       catch 
       { 
        trans.Rollback(); 
        throw; 
       } 

       // Selecting only "c" column 
       com.CommandText = "SELECT c FROM Test"; 
       using (DbDataReader dr = com.ExecuteReader()) 
       { 
        if (dr.Read()) 
         MessageBox.Show(Convert.ToInt32(dr["c"]).ToString()); 
         // Showing correct value, ok 
       } 

       // Uncomment these lines to solve problem 
       //con.Close(); 
       //OracleConnection.ClearAllPools(); 
       //con.Open(); 

       // Selecting all fields * from table 
       com.CommandText = "SELECT * FROM Test"; 
       using (DbDataReader dr = com.ExecuteReader()) 
       { 
        MessageBox.Show(dr.GetSchemaTable().Rows.Count.ToString() + "/" + dr.FieldCount.ToString()); 
        // HERE IS THE PROBLEM: message are showing 2/2, but table haves 3 fields 

        if (dr.Read()) 
         MessageBox.Show(Convert.ToInt32(dr["c"]).ToString()); 
        // Here throws IndexOutOfRangeException: Unable to find specified column in result set 
       } 
      } 
     } 
     finally 
     { 
      con.Close(); 
     } 
    } 
} 
+0

私には、ある種のメタデータキャッシュのように聞こえます。たぶん 'OracleConnection.PurgeStatementCache()'メソッドは役に立ちますか? –

+0

私は、列を追加した後、選択する前にPurgeStatementCacheを試しましたが、機能しませんでした。 – rkawano

+0

'OracleTransaction'は廃棄されるべきで、それ自身の' using'ブロックを持つべきです。 ['OracleCommand.CreateCommand'](http://docs.oracle.com/html/B28089_01/OracleConnectionClass.htm#i1001011)を使用することもできます。これにより、コマンドを自分自身に割り当てる必要がなくなります。 – WhiteKnight

答えて

1

:ここ

はテストに大きいが、簡単なコードです。私は

+0

実際のアプリケーションではトランザクションを使用しており、動作はまったく同じです。接続を再開しても解決されませんが、アプリケーションの再起動が解決されました。 – rkawano

+0

OracleConnection.ClearAllPoolsをコールしますか?皆さんが接続プールを使用している場合、「閉じる」と呼んでも、フレームワークは接続オブジェクトをプール内に保持します – Ulises

+0

ClearAllPoolsが機能しました!私は、列を追加するためにコマンドを実行し、接続を閉じ、clearAllPoolsを実行して接続を再度開きます。うまく動作し、私はすべてのアプリケーションを再起動する必要はありません。ありがとう! – rkawano

0

がトランザクションを作成するためにOracleConnection.BeginTransactionを使用してみてください(あなたがOracleConnection.ClearAllPoolsを使用する必要があります)あなたがリーダーを実行する直前に、あなたは再びそれを挿入し、開いた直後に接続を閉じることにより、これを確認することができ思考し、その後Commitよ選択する前に、ドキュメントのexampleに示されているようなものです。

+0

私は、カラムを追加する前にトランザクションを開始しようとしましたが、値を挿入した後コミットしましたが、うまくいきませんでした。 – rkawano

+0

あなたのトランザクションの使用状況を示すためにあなたの例を編集してください。 – WhiteKnight

+0

edited on button2_Click – rkawano