[oracle]varcharのデータ型にバイナリを入れることができるか。
2011/01/22
jdbc
oracle
sql
Oracleです。テーブルのデータ型で悩み中です。どういう悩みかというと、char,varchar2のデータ型にバイナリのデータ(ようするに生のデータ)を入るのか、というものです。本来は、そういう用途だと、BLOBとかRAWの型だというのは承知のうえで。
で、入れてそれを使えるのかという実験です。
もしかして、他に方法があるかもしれませんが、結論からいうとできないです。
>_<!
ちなみに環境は、プログラマメモ2: oracleオレオレ開発環境、まずは接続で使ったものと同じです。
NLS_CHARACTERSETは、
select * from nls_database_parameters where parameter ='NLS_CHARACTERSET';
NLS_CHARACTERSET
JA16SJISTILDE
です。
下記ようなテーブルを用意します。
create table aaa
(
code varchar(30),
moji1 varchar(10 BYTE),
moji2 varchar(10 BYTE),
moji3 raw(10),
moji4 blob
);
最初の列に文字コードを指定して、データとしてその文字コードで表現された文字を入れたいというような発想です。
列長セマンティックをよく知らず設定したりしてますが...
検証用コードです。
import java.io.File;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class TestDB_moji {
public static void main(String[] args) throws SQLException,
ClassNotFoundException, IOException {
String s = "仲";
aaa("utf8", s);
aaa("sjis", s);
// aaa("jis", s);
}
/*
* 目的 VARCHARの項目にバイナリなデータを保存できるのかな検証
*
* シナリオ 文字コードを指定して,setBytesを使って登録し、とりだして復元できるか調べる
*/
static void aaa(String code, String s) throws SQLException,
IOException {
Connection connection = DriverManager.getConnection(
"jdbc:oracle:thin:@192.168.24.135:1521:test", "system",
"oracle");
// DatabaseMetaData meta = connection.getMetaData();
try {
if(true){
PreparedStatement statement = null;
String q = "INSERT INTO aaa(code, moji1, moji2, moji3, moji4) VALUES(?, ? , ?, ?, ?)";
statement = connection.prepareStatement(q);
// 文字コードで指定したバイト配列
byte[] bs = s.getBytes(code);
// まず普通に入れると
statement.setString(1, code);
statement.setString(2, new String(bs));// varchar2
statement.setBytes(3, bs);// varchar2
statement.setBytes(4, bs);// raw
statement.setBytes(5, bs);// blob
// statement.setBlob(5, new ByteArrayInputStream(bs));// blob
statement.executeUpdate();
connection.commit();
}
// バイトで値入れたら復元できるかな
{
ResultSet resultSet = null;
Statement statement = connection.createStatement();
resultSet = statement.executeQuery("select * from aaa");
int i = 0;
StringBuilder builder = new StringBuilder();
while (resultSet.next()) {
String c = resultSet.getString(1);
builder.append(
String.format(
"%d code:[%s] moi1:[%s] moi2:[%s] moi3:[%s] moi4:[%s]%n",
++i,
resultSet.getString(1), resultSet
.getString(2), new String(resultSet
.getBytes(3), c), new String(
resultSet.getBytes(4), c),
new String(resultSet.getBytes(5), c)));
}
resultSet.close();
statement.close();
System.out.println(builder);
Utils.write(new File("/z/a.txt"), new String(builder).getBytes());
}
} finally {
connection.close();
}
}
}
で、実行します。
こんな感じで登録されてます。
検証のプログラムの実行結果は、
1 code:[utf8] moi1:[莉イ] moi2:[E4BBB2] moi3:[仲] moi4:[仲]
2 code:[sjis] moi1:[仲] moi2:[9287] moi3:[仲] moi4:[仲]
raw,blobはjava側のgetBytesで復元できます。がvarcharでは復元できませんし、文字列になってしまってる...
: