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 に変換しないためです。

どうすればこの問題を解決できますか?

私が行ったいくつかの追加のテスト: また、null 可能/null 不可の新しい列をデフォルト値で挿入しました:

**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 は適切ですが、列の 1 つが null ではなく、デフォルト値が設定されていることを除きます。この問題の解決策はありますか?

間違ったコード (ColumnC) を返す列の型をCHAR(1) null デフォルト '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)

4

1 に答える 1

0

この新機能に問題がある可能性があります:

NOT NULL 列に DEFAULT 句を指定すると、デフォルト値がメタデータとして格納されますが、列自体にはデータが移入されません。ただし、新しい列を指定する後続のクエリは、デフォルト値が結果セットに返されるように書き換えられます。この最適化された動作は、ALTER TABLE 操作の一部として、Oracle Database が新しく作成された列の各行をデフォルト値で更新し、表に定義された更新トリガーを起動した以前のリリースとは異なります。このリリースでは、デフォルトはメタデータとしてのみ保存されるため、トリガーは起動されません。

理由はわかりませんが。データベースサーバーでは問題なく動作しているようです。DBMS_METADATA.GET_DDL を使用すると、DDL または DML に関係なく、型情報は正しいようです。

これは、ツールが独自のメタデータ クエリを使用していることを意味しますが、おそらく間違っています。大きな問題は、どのツールを使用しているのかということです。"OraDBType" とは何ですか? この XML はどこから来たのですか?

XML の作成に使用されている SQL ステートメントを正確に確認するには、トレースを有効にする必要がある場合があります。

推測するに、問題は遅延セグメント作成に関連している可能性があります。その機能が有効になっている場合、最初にテーブルを作成するときにセグメントはありません。遅延セグメント作成により、多くのスペースを節約できますが、セグメント情報が常に存在すると想定するクエリで問題が発生する可能性があります。

于 2012-04-24T18:02:08.230 に答える