我開發了一個基於外部定義創建表的應用程序。如果這些定義發生更改,則應用程序將刪除並重新創建受影響的表。在連接打開時必須這樣做,因爲該任務是一組任務的一部分。但是,如果我查詢一個隨後用「select *」更改的表,我會得到舊定義的列。如果列已添加到表中,「select *」不會看到它。下面是一個說明這是一個示例代碼:使用如何讓表「select *」在表被修改後相應地工作?
private static void OraSelectStarProblem()
{
var tabDef1 = "CREATE TABLE TEMP_PS_000 (SESSIONID RAW(16), EXECNR NUMBER, DUEDATE DATE)";
//var tabDef2 = "CREATE TABLE TEMP_PS_000 (YASESSIONID RAW(16), YAEXECNR NUMBER, YADUEDATE DATE, NEWFIELD VARCHAR2(100))";
var tabDef2 = "CREATE TABLE TEMP_PS_000 (YADUEDATE DATE, NEWFIELD VARCHAR2(100), SOMEOTHER integer)"; // causes ORA-00932 when querying
var selectCmd = "select * from TEMP_PS_000";
using (var conn = new OracleConnection(GetConnStr()))
{
conn.Open();
//PerformSelectStar(selectCmd, conn);
DropTempTable(conn);
Console.Write("Creating TEMP_PS_000 with 3 columns... ");
using (var cmd = conn.CreateCommand())
{
cmd.CommandText = tabDef1;
cmd.ExecuteNonQuery();
}
Console.WriteLine("Done!");
PerformSelectStar(selectCmd, conn);
//conn.PurgeStatementCache(); // no effect
//conn.FlushCache(); // no effect
/*Console.WriteLine("Resetting connection");
conn.Close();
OracleConnection.ClearPool (conn);
conn.Open();*/
DropTempTable(conn);
//conn.PurgeStatementCache(); // no effect
//conn.FlushCache(); // no effect
Console.Write("Creating TEMP_PS_000 with 4 columns... ");
using (var cmd = conn.CreateCommand())
{
cmd.CommandText = tabDef2;
cmd.ExecuteNonQuery();
}
Console.WriteLine("Done!");
PerformSelectStar(selectCmd, conn);
}
}
private static void DropTempTable(OracleConnection conn)
{
using (var cmd = conn.CreateCommand())
{
cmd.CommandText = "begin drop_table('TEMP_PS_000'); end;";
cmd.ExecuteNonQuery();
}
}
private static void PerformSelectStar(string selectCmd, OracleConnection conn)
{
try
{
using (var cmd = conn.CreateCommand())
{
cmd.CommandText = selectCmd;
var dataAdapter = new OracleDataAdapter(cmd);
var dataSet = new DataSet();
dataAdapter.Fill(dataSet);
var columns = "";
foreach (DataColumn column in dataSet.Tables[0].Columns)
{
columns += column.ColumnName + " ";
}
Console.WriteLine("Columns: " + columns);
}
}
catch (Exception ex)
{
Console.WriteLine("PerformSelectStar: " + ex.Message);
}
}
軟件版本:4.5.1 .NET和Oracle 12.1
如果重置連接部分被激活,「SELECT *」的作品,但隨後臨時表中的所有數據都會刷新,這是不希望的。
我想知道是否有某種方法告訴ODP.net或Oracle--無論哪種原因導致這種奇怪的行爲 - 表的定義已被更改,並且它應該在執行前重新讀取表定義「選擇 *」。
爲什麼要這樣做?看起來像它違背了關係數據庫系統中的觀點,您應該查看DocumentDB解決方案......如果您確實需要這樣做,請使用數據庫提供的元數據視圖來獲取列的明確列表並將其用於查詢而不是* – Milney
@Milney這些表中的數據與標準化數據庫上的SQL查詢結合使用。雖然把它放在其他地方是可能的,但它也會導致查詢變得更加複雜(即代碼將更難以閱讀和維護)。 –
問題可以解決:訣竅是以不影響結果的方式稍微修改語句,如下所示:http://stackoverflow.com/a/16861388/3424360 –