数据库列类型CHAR的XML OraDbType代码错误

时间:2012-04-23 09:53:37

标签: xml database oracle11g

我从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)默认'S'不为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。

如何解决此问题?

我做过一些额外的测试: 还插入了可以为nullable / not nullable且具有默认值的新列:

**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默认'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)

1 个答案:

答案 0 :(得分:0)

您可能对此new feature

有疑问
  

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

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

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

您可能需要启用跟踪,以确切了解用于创建XML的SQL语句。

如果我不得不猜测,问题可能与deferred segment creation有关。如果启用了该功能,则在首次创建表时没有任何段。延迟段创建可以节省大量空间,但是对于假设始终存在段信息的查询,它可能会导致问题。