谷本 心 in せろ部屋

はてなダイアリーから引っ越してきました

DatabaseMetaDataでドコまで取れるか、何が取れないのか

昨日のエントリーで、ちょっと嘘ついちゃいました。
ユーザ定義の詳細は、DatabasetMetaDataの別メソッドを使えば、
もうちょっと取れます。


ということで、
DatabaseMetaDataでどんな情報が取れるか見ていこう。


こんなコードを書いてみる。

public class DmdTest {
	private static final String PATH = "j2ee.dicon";

	public static void main(String[] args) throws Exception {
		S2Container container = S2ContainerFactory.create(PATH);
		container.init();

		DataSource ds = (DataSource) container.getComponent(DataSource.class);
		Connection conn = ds.getConnection();

		DatabaseMetaData dmd = ConnectionUtil.getMetaData(conn);
		ResultSet rs = dmd.getProcedures(null, "接続ユーザ名", "%");

		printResultSet(rs);
	}

	private static void printResultSet(ResultSet rs) throws SQLException {
		ResultSetMetaData rsMetaData = rs.getMetaData();
		int columnSize = rs.getMetaData().getColumnCount();

		StringBuffer buf = new StringBuffer("|*Column Names");
		for (int i = 1; i < columnSize; i++) {
			buf.append("|*" + rsMetaData.getColumnName(i));
		}
		System.out.println(buf.append("|"));

		while (rs.next()) {
			buf = new StringBuffer("|").append(rs.getRow());
			for (int i = 1; i < columnSize; i++) {
				buf.append("|" + rs.getObject(i));
			}
			System.out.println(buf.append("|"));
		}
	}
}

printResultSetは、ResultSetの内容をはてなのテーブル形式で、標準出力に表示するだけのメソッド。


まずは、DatabaseMetaData#getProceduresで取れる値。

ResultSet rs = dmd.getProcedures(null, "接続ユーザ", "%");
Column Names PROCEDURE_CAT PROCEDURE_SCHEM PROCEDURE_NAME NULL NULL NULL REMARKS
1 null 接続ユーザ名 NEW_PERSON null null null Standalone procedure or function
2 null 接続ユーザ名 NEW_PERSON_ARRAY null null null Standalone procedure or function
3 null 接続ユーザ名 PERSON_NAME null null null Standalone procedure or function
4 null 接続ユーザ名 PERSON_NAME_MERGE null null null Standalone procedure or function
5 null 接続ユーザ名 SALES_TAX null null null Standalone procedure or function
6 null 接続ユーザ名 SALES_TAX2 null null null Standalone procedure or function
7 null 接続ユーザ名 SALES_TAX3 null null null Standalone procedure or function
8 null 接続ユーザ名 SALES_TAX4 null null null Standalone procedure or function

特に問題ないですね。


続いて、DatabaseMetaData#getColumnsで取れる値。

ResultSet rs = dmd.getProcedureColumns(null, "接続ユーザ名", "%", null);
Column Names PROCEDURE_CAT PROCEDURE_SCHEM PROCEDURE_NAME COLUMN_NAME COLUMN_TYPE DATA_TYPE TYPE_NAME PRECISION LENGTH SCALE RADIX NULLABLE REMARKS SEQUENCE OVERLOAD
1 null 接続ユーザ名 NEW_PERSON null 5 1111 接続ユーザ名.PERSON null null null 10 1 null 1 null
2 null 接続ユーザ名 NEW_PERSON ID 1 3 NUMBER 22 22 null 10 1 null 2 null
3 null 接続ユーザ名 NEW_PERSON NAME 1 12 VARCHAR2 null null null 10 1 null 3 null
4 null 接続ユーザ名 NEW_PERSON_ARRAY null 5 1111 VARRAY null null null 10 1 null 1 null
5 null 接続ユーザ名 NEW_PERSON_ARRAY null 4 1111 接続ユーザ名.PERSON null null null 10 1 null 2 null
6 null 接続ユーザ名 NEW_PERSON_ARRAY ID1 1 3 NUMBER 22 22 null 10 1 null 3 null
7 null 接続ユーザ名 NEW_PERSON_ARRAY NAME1 1 12 VARCHAR2 null null null 10 1 null 4 null
8 null 接続ユーザ名 NEW_PERSON_ARRAY ID2 1 3 NUMBER 22 22 null 10 1 null 5 null
9 null 接続ユーザ名 NEW_PERSON_ARRAY NAME2 1 12 VARCHAR2 null null null 10 1 null 6 null
10 null 接続ユーザ名 PERSON_NAME null 5 12 VARCHAR2 null null null 10 1 null 1 null
11 null 接続ユーザ名 PERSON_NAME USER 1 1111 接続ユーザ名.PERSON null null null 10 1 null 2 null
12 null 接続ユーザ名 PERSON_NAME_MERGE null 5 12 VARCHAR2 null null null 10 1 null 1 null
13 null 接続ユーザ名 PERSON_NAME_MERGE USERS 1 1111 VARRAY null null null 10 1 null 2 null
14 null 接続ユーザ名 PERSON_NAME_MERGE null 1 1111 接続ユーザ名.PERSON null null null 10 1 null 3 null
15 null 接続ユーザ名 SALES_TAX SALES 1 3 NUMBER 22 22 null 10 1 null 1 null
16 null 接続ユーザ名 SALES_TAX TAX 4 3 NUMBER 22 22 null 10 1 null 2 null
17 null 接続ユーザ名 SALES_TAX2 null 5 3 NUMBER 22 22 null 10 1 null 1 null
18 null 接続ユーザ名 SALES_TAX2 SALES 1 3 NUMBER 22 22 null 10 1 null 2 null
19 null 接続ユーザ名 SALES_TAX3 SALES 2 3 NUMBER 22 22 null 10 1 null 1 null
20 null 接続ユーザ名 SALES_TAX4 SALES 1 3 NUMBER 22 22 null 10 1 null 1 null
21 null 接続ユーザ名 SALES_TAX4 TAX 4 3 NUMBER 22 22 null 10 1 null 2 null
22 null 接続ユーザ名 SALES_TAX4 TOTAL 4 3 NUMBER 22 22 null 10 1 null 3 null

型がユーザ定義型 (STRUCT) の所は、TYPE_NAMEが「接続ユーザ名.PERSON」と問題なく取れてるけど、
配列 (VARRAY) はTYPE_NAMEが全部「VARRAY」となってて、期待する「接続ユーザ名.PERSON_ARRAY」が取れない。
うーん。。。


一応、DatabaseMetaData#getUDTsで詳細も見てみる。

ResultSet rs = dmd.getUDTs("%", "接続ユーザ名", "%", null);
Column Names TYPE_CAT TYPE_SCHEM TYPE_NAME CLASS_NAME DATA_TYPE
1 null 接続ユーザ名 PERSON null STRUCT

DATA_TYPEもちゃんと取れて問題なし。