Gblog

おもにTips

ANYDATA 型

ANYDATAは、TYPEオブジェクトです。列の型にも定義できますが、データを操作するファンクションなども定義されています。

STS触ったついでに、サンプルを。

 

作成は、普通にできる。

SQL> create table test1 ( id number, col1  anydata);

Table created.

SQL> desc test1
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 ID                                                 NUMBER
 COL1                                               PUBLIC.ANYDATA

 

INSERT はエラー。

SQL> INSERT INTO TEST1 VALUES (1,1);
INSERT INTO TEST1 VALUES (1,1)
                            *
ERROR at line 1:
ORA-00932: inconsistent datatypes: expected - got NUMBER

 

CONVERT ファンクションを使う必要があります。

SQL> insert into test1 values (1,anydata.convertnumber(1));

1 row created.

SQL> insert into test1 values (2,anydata.convertchar('x'));

1 row created.

SQL> insert into test1 values (3,anydata.convertvarchar2('y'));

1 row created.

SQL> insert into test1 values (4,anydata.convertdate(sysdate));

1 row created.

SQL> commit;

Commit complete.

 

普通に検索してもデータは見えません。

SQL> col col1 for a10
SQL> select * from test1;

        ID COL1()
---------- ----------
         1 ANYDATA()
         2 ANYDATA()
         3 ANYDATA()
         4 ANYDATA()

 

ACCESS ファンクションを使用すると見えるけど、型がマッチしない行は NULL。

SQL> col col1 for a20
SQL> select id, anydata.accessvarchar2(col1) as col1 from test1;

        ID COL1
---------- --------------------
         1
         2
         3 y
         4

 

CASE文で対応可能

SQL> select id,
  2    case anydata.gettypename(col1)
  3      when 'SYS.NUMBER'   then anydata.accessnumber(col1)
  4      when 'SYS.CHAR'     then anydata.accesschar(col1)
  5      when 'SYS.VARCHAR2' then anydata.accessvarchar2(col1)
  6      when 'SYS.DATE'     then anydata.accessdate(col1)
  7      else null
  8    end as col1
  9  from test1;
    when 'SYS.CHAR'     then anydata.accesschar(col1)
                                     *
ERROR at line 4:
ORA-00932: inconsistent datatypes: expected NUMBER got CHAR

 ???

 

どうやら、戻り値の型は合わせる必要があるみたいです。。。

SQL> select id,
  2    case anydata.gettypename(col1)
  3      when 'SYS.NUMBER'   then to_char(anydata.accessnumber(col1))
  4      when 'SYS.CHAR'     then anydata.accesschar(col1)
  5      when 'SYS.VARCHAR2' then anydata.accessvarchar2(col1)
  6      when 'SYS.DATE'     then to_char(anydata.accessdate(col1))
  7      else null
  8    end as col1
  9  from test1;

        ID COL1
---------- --------------------
         1 1
         2 x
         3 x
         4 2019-09-13 13:21:24