1

从 Oracle DB 检索的 XML 有一个奇怪的问题。我正在使用 OraDB11g,接下来将描述我的问题:

当我创建一个具有 CHAR 类型列的表并从查询中获取 XML 并返回一个带有表行的游标时,我得到了假定的正确 OraDbType 代码 104:

表创建:

create table AA_Table1
(
ID number(2,0) not null,
**ColumnA char(1) null,
ColumnB char(1) default 'S' not null,**
constraint PK_AA_Table1
primary key ( ID )
)
tablespace "X"
storage
(
...
)
compress for all operations
;

和返回的 XML:

<?xml version="1.0" encoding="utf-16"?>
<xs:schema id="o_ListaTable" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:msprop="urn:schemas-microsoft-com:xml-msprop">
<xs:element name="o_ListTable" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="o_List" msprop:REFCursorName="REFCursor">
<xs:complexType>
<xs:sequence>
<xs:element name="ID" msprop:OraDbType="111" type="xs:short" minOccurs="0" />
**<xs:element name="COLUMNA" msprop:OraDbType="104" type="xs:string" minOccurs="0" />
<xs:element name="COLUMNB" msprop:OraDbType="104" type="xs:string" minOccurs="0" />** 
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>

但是...当我在表上插入另一列并更改它之后,我在返回的 XML 上为新添加的列得到了错误的 OraDBType 代码...

添加了新列: alter table AA_Table1 add ColumnC char(1) default 'S' not null;

返回的 XML 是:

<?xml version="1.0" encoding="utf-16"?>
<xs:schema id="o_ListaTable" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:msprop="urn:schemas-microsoft-com:xml-msprop">
<xs:element name="o_ListTable" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="o_List" msprop:REFCursorName="REFCursor">
<xs:complexType>
<xs:sequence>
<xs:element name="ID" msprop:OraDbType="111" type="xs:short" minOccurs="0" />
<xs:element name="COLUMNA" msprop:OraDbType="104" type="xs:string" minOccurs="0" />
<xs:element name="COLUMNB" msprop:OraDbType="104" type="xs:string" minOccurs="0" />
**<xs:element name="COLUMNC" msprop:OraDbType="126" type="xs:string" minOccurs="0" />**
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>

我的问题是:为什么这个 OraDbType 代码不同?检查是否在表创建上创建了相同的列类型 CHAR(1) NOT NULL DEFAULT 'S' 并且 OraDbType 没问题,所以我认为这可能是一个错误......

因此,我无法使用正确的 XML 解析器将 CHAR(1) 列转换为我想要的其他类型,在这种情况下,将其转换为 .Net bool 类型。我的解析器现在忽略了 OraDbType 代码 126,因为这也是用于 nvarchar2 的代码,我不会将 nvarchar2 转换为 bool。

我怎么解决这个问题?

我已经完成了一些额外的测试:还插入了可以为空/不可为空且具有默认值的新列:

**alter table AA_Table1 add ColumnD char(1);
alter table AA_Table1 add ColumnE char(1) not null;
alter table AA_Table1 add ColumnF char(1) default 'S';**

返回的 XML 是:

<?xml version="1.0" encoding="utf-16"?>
<xs:schema id="o_ListTable" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:msprop="urn:schemas-microsoft-com:xml-msprop">
<xs:element name="o_ListTable" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="o_Lista" msprop:REFCursorName="REFCursor">
<xs:complexType>
<xs:sequence>
<xs:element name="COLUMNA" msprop:OraDbType="104" type="xs:string" minOccurs="0" />
<xs:element name="COLUMNB" msprop:OraDbType="104" type="xs:string" minOccurs="0" />
<xs:element name="COLUMNC" msprop:OraDbType="126" type="xs:string" minOccurs="0" />
**<xs:element name="COLUMND" msprop:OraDbType="104" type="xs:string" minOccurs="0" />
<xs:element name="COLUMNE" msprop:OraDbType="104" type="xs:string" minOccurs="0" />
<xs:element name="COLUMNF" msprop:OraDbType="104" type="xs:string" minOccurs="0" />**
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>

所有 OraDbTypes 都是正确的,除了一个不为空且具有默认值的列。这个问题有什么解决办法吗?

如果我将返回错误代码的列的类型 (ColumnC) 更改为CHAR(1) null default 'S'然后再次将其更改为原始类型CHAR(1) not null default 'S',我得到了正确的ORaDbType 代码为 104,而不是 126。这种行为很奇怪 - 这可能是 Oracle 错误吗?

我正在使用以下 Oracle DLL 和相应版本:

oci.dll(版本 11.2.0.1)

Oracle.DataAccess.dll(版本 4.112.3.0)

orannzsbb11.dll(版本 11.0.0.1)

oraocci11.dll(版本 11.2.0.3)

OraOps11w.dll(版本 2.112.3.0)

4

1 回答 1

0

您可能对这个新功能有疑问

如果为 NOT NULL 列指定 DEFAULT 子句,则默认值将存储为元数据,但列本身不会填充数据。但是,指定新列的后续查询将被重写,以便在结果集中返回默认值。这种优化行为与早期版本不同,当作为 ALTER TABLE 操作的一部分时,Oracle 数据库使用默认值更新新创建的列中的每一行,然后触发表上定义的任何更新触发器。在此版本中,不会触发任何触发器,因为默认值仅存储为元数据。

虽然我不知道为什么。它似乎在数据库服务器上工作正常。使用 DBMS_METADATA.GET_DDL,无论 DDL 还是 DML,类型信息似乎都是正确的。

这意味着您的工具正在使用自己的元数据查询,可能是错误的。最大的问题是,您使用的是什么工具?什么是“OraDBType”,这个 XML 来自哪里?

您可能需要启用跟踪,以准确查看用于创建 XML 的 SQL 语句。

如果我不得不猜测,问题可能与延迟段创建有关。如果启用了该功能,则在您第一次创建表时没有段。延迟段创建可以节省大量空间,但它可能会导致假设始终存在段信息的查询出现问题。

于 2012-04-24T18:02:08.230 回答