簡體   English   中英

選擇最近在ODP.NET中用ALTER TABLE插入的列時出錯

[英]Error selecting column recently inserted with ALTER TABLE in ODP.NET

1-使用Oracle.DataAccess連接到Oracle XE

2-執行命令以將列添加到表中:alter table TABLE add COLUMN b int;

3-執行命令以選擇此列

4-用DataReader讀取。 應用程序引發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();
        }
    }
}

聽起來當您執行讀取器時,插入事務尚未提交。 我想您可以通過在插入插入之后關閉連接並在執行讀取器之前再次打開連接來驗證此連接(您可能需要使用OracleConnection.ClearAllPools)

嘗試使用OracleConnection.BeginTransaction創建一個事務,然后選擇Commit ,然后再選擇,如文檔示例中所示。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM