我将 Oracle 的 ODAC.NET 用于针对 Oracle 11 Express 数据库的 .NET 3.5 项目,并且我看到了我无法解释的行为(而且似乎无法解决)。
ODAC应该是最新的,我3天前刚拉的,不过版本如下:
- Oracle.DataAccess.dll 版本 2.112.3.0(第 5 版)
- oci.dll(即时客户端)版本 11.2.0.1
我有一个表 People,它有 3 列:
- ID
- 名
- 姓
在代码中,我运行 ALTER TABLE 命令,使用OracleCommand.ExecuteNonQuery
, 将名为“MIDDLE_NAME”的新列添加到表中。该命令成功。如果我使用 Oracle SQL Developer 查看表格,就会显示列。一切都很好。
现在,如果我在执行 alter table 后立即使用OracleCommand.ExecuteReader
命令文本运行 use SELECT * FROM People
,我将返回只有 3 列的数据,而不是 4!
这是重现问题的代码:
public void FieldTest()
{
var sql1 = "CREATE TABLE People (" +
"ID NUMBER PRIMARY KEY, " +
"FirstName NVARCHAR2 (200), " +
"LastName NVARCHAR2 (200) NOT NULL)";
var sql2 = "ALTER TABLE People " +
"ADD Middle_Name NUMBER";
var sql3 = "SELECT * FROM People";
var sql4 = "SELECT column_name FROM all_tab_cols WHERE table_name = 'PEOPLE'";
var cnInfo = new OracleConnectionInfo("192.168.10.246", 1521, "XE", "system", "password");
var connectionString = BuildConnectionString(cnInfo);
using (var connection = new OracleConnection(connectionString))
{
connection.Open();
using (var create = new OracleCommand(sql1, connection))
{
create.ExecuteNonQuery();
}
using (var get = new OracleCommand(sql3, connection))
{
using (var reader = get.ExecuteReader())
{
Debug.WriteLine("Columns: " + reader.FieldCount);
// outputs 3, which is right
}
}
using (var alter = new OracleCommand(sql2, connection))
{
alter.ExecuteNonQuery();
}
using (var get = new OracleCommand(sql3, connection))
{
using (var reader = get.ExecuteReader())
{
Debug.WriteLine("Columns: " + reader.FieldCount);
// outputs 3, which is *wrong* <---- Here's the problem
}
}
using (var cols = new OracleCommand(sql4, connection))
{
using (var reader = cols.ExecuteReader())
{
int count = 0;
while (reader.Read())
{
count++;
Debug.WriteLine("Col: " + reader.GetString(0));
}
Debug.WriteLine("Columns: " + count.ToString());
// outputs 4, which is right
}
}
}
}
我尝试了一些方法来防止这种行为,但它们都没有给我第四列:
- 我关闭连接并重新打开它
- 我用 new
OracleConnection
代替SELECT
ALTER
- 我
OracleConnection
对 theSELECT
和 for the使用相同的ALTER
- 我用 new
OracleCommand
代替SELECT
ALTER
- 我
OracleCommand
对 theSELECT
和 for the使用相同的ALTER
- 我呼吁和
PurgeStatementCache
之间的联系ALTER
SELECT
- 我呼吁和
FlushCache
之间的联系ALTER
SELECT
- 我明确地
Close
将Dispose
andOracleCommand
(OracleConnection
与 using 块相反)用于ALTER
andSELECT
- 重新启动调用 PC 和托管 Oracle 数据库的 PC。
如果我通过执行 a 查看列列表SELECT * FROM all_tab_cols
,则新列就在那里。
唯一似乎可靠工作的是关闭应用程序并重新启动它(它来自单元测试,但它是测试主机的关闭和重新启动)。然后我得到第四列。有时我可以使用断点并重新执行查询,并且会出现第 4 列,但没有任何东西可以通过直接执行代码来特别重复(意味着没有设置断点并将执行点向上移动)。
ODAC 内部的某些东西似乎正在缓存该表的模式,但我可以弄清楚是什么、为什么或如何阻止它。任何人都有这方面的经验,或者想法我可以如何防止它?