1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Oracle AI Databaseでマルチレイアウトのテーブルを作る方法その2

Last updated at Posted at 2025-12-18

本記事はOracle Cloud Infrastructure Advent Calendar 2025 シリーズ2 の18日目とJPOUG Advent Calendar 2025の18日目のダブルポストです。

はじめに

本記事は過去記事の続きです。
Oracle Database 9i以降ANYDATA型という多種多様なデータ型を格納できるデータ型が存在します。マニュアルなど公式文書では「SYS.ANYDATA」と表現されていますが実利用の際にスキーマ名修飾は不要です。もちろんつけてもかまいません。

このデータ型を使用することにより列数は固定になりますがレコードによって該当列に格納されるデータ型が異なる状態を作ることが可能です。とはいえANYDATAはその1で紹介したオブジェクト型も格納可能です。本記事の方法でもオブジェクト型と併用することでレコードにより列数が異なるテーブルも作成可能です。余談ですが逆にオブジェクト型内の列の型にANYDATAを指定することも可能です。

本記事の検証環境はATP26aiです。

テーブルの作成

create table anydata1 (id number, col1 anydata);

と、データ型をANYDATAで指定するだけです。今回の記事ではanydataの列は一つだけで検証しますが、以下のように複数列作成することも可能です。

create table anydata2 (id number, col1 anydata, col2 anydata, col3 anydata);

データの格納

ANYDATA型の列や変数へのデータのハンドリングはANYDATA型で用意しているファンクションを経由して操作する必要があり、VARCHAR2型やNUMBER型のデータを直接出し入れすることはできません。データの格納はANYDATA.ConvertNumber(12345)のように「Convert+型名」のファンクションを使用します。

insert into anydata1 values(1, anydata.convertnumber(12345));
insert into anydata1 values(2, anydata.convertvarchar2('Hello World'));
insert into anydata1 values(3, anydata.convertdate(current_date));
commit;

データの取り出し

単にselectしただけでは中身のデータへの直接アクセスができないため以下のような表示なります。

SQL> select * from anydata1;

        ID
----------
COL1()
--------------------------------------------------------------------------------
         1
ANYDATA()

         2
ANYDATA()

         3
ANYDATA()

格納時と同様ANYDATA型のファンクション経由で取り出す必要があります。データの表示のためにはまずANYDATA.GetTypeName()で型名を確認し、確認できたデータ型に応じてANYDATA.AccessNumber()のように「Access+型名」のファンクションを使用します。ANYDATA.GetTypeName()で戻る型名は「SYS.NUMBER」のように大文字で指定してください。

SQL> select
  2      id,
  3      case
  4          when t.col1.gettypename() = 'SYS.NUMBER' then
  5              to_char(sys.anydata.accessnumber(t.col1))
  6          when t.col1.gettypename() = 'SYS.VARCHAR2' then
  7              sys.anydata.accessvarchar2(t.col1)
  8          when t.col1.gettypename() = 'SYS.DATE' then
  9              to_char(sys.anydata.accessdate(t.col1), 'yyyy-mm-dd hh24:mi:ss')
 10          else '非対応の型'
 11      end as value_string
 12  from
 13      anydata1 t;

        ID
----------
VALUE_STRING
--------------------------------------------------------------------------------
         1
12345

         2
Hello World

         3
2025-12-09 12:17:26

もっと簡単に表示する方法としてXMLTYPE型に変換する方法があります。オブジェクト型についてはConvertObject()はあるのですがAccessObject()が存在しません。そのため、SQL*Plusなどのツールで内容を確認するためには、文字列形式で表示するメンバー・ファンクションをコールするかこの方法を使用する必要があります。以下はその1で作成したオブジェクト型を含むレコードの追加後に全件SELECTしてみた例となります。

SQL> select id, xmltype(col1) from anydata1;

        ID
----------
XMLTYPE(COL1)
--------------------------------------------------------------------------------
         1
<ANYDATA>12345</ANYDATA>

         2
<ANYDATA>Hello World</ANYDATA>

         3
<ANYDATA>25-12-09</ANYDATA>

         4
<REC2_TYPE>
  <ID>12B00A05DB614FF0BF938EC297F64ED5</ID>
  <COL101>9</COL101>
  <COL102>ABC</COL102>
  <COL103>9999</COL103>
  <COL104>Oracle</COL104>
</REC2_TYPE>
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?