bcp で SQLServer のデータをCSVで書き出す

/ db

メモ。

C:\>bcp DB.dbo.TABLE out c:\test.csv -c -t "," -S localhost\sqlexpress -U sa

こんな感じ?

でも、これだと単純にデータ間にカンマを入れるだけなので、厳密なCSVではないんだよなあ。データ中にカンマが入るような場合だと、カラムの区切り文字と区別つかなくなっちゃうから、本来はカラムごとに引用符付きで出力したいんだけど、bcp ユーティリティでは方法が分からず。フォーマットとか使えば良いのかもしれないけど、テーブルごとに用意するのでは、面倒っちいです。

やっぱり、自分でDBを読み込んでCSVで書き出すようなプログラムを書かないとダメですかね。うーん、Windows は苦手なので逡巡します。

CSVファイルをPostgreSQLに取り込む方法

/ db

Excel で作成したデータを DB に取り込むシーンって、意外とあるんだけど、これが厄介。

そういうとき自分は、Excel データを csv 形式で出力してから、それを postgresql に COPY で取り込むような流れでやってるんですが、

COPY test FROM '/home/postgres/test.csv' WITH delimiter ',' null '';

こういう風にすると、データ中に「"aaa,bbb"」みたいな項目があると、そのカンマにも反応しちゃってカラムが区切られてしまうので、

ERROR:  extra data after last expected column

なんて怒られてしまう。

どうしたもんかなーと思って調べていたら、いつの間にやら COPY は CSV 対応している模様。

COPY test FROM '/home/postgres/test.csv' WITH CSV;

これでOKでした。

CSV への対応は PostgreSQL 8系以降でのサポートっぽい。ちょっとしたことですが、これは便利。

JUnit4 を試してみる

今度のお仕事でようやく Java を 1.4 から 5.0 に進化させることができたので、合わせて Junit も 3.8 から 4.3 にシフト。Java5 を触り始めて、もはやアノテーション無しではコードを書けない身体になってしまったので、ここは外せない。

アノテーション 説明 JUnit3.8では
@Test テストメソッドであることを示す testXxx()
@Before 各テストメソッドの実行前に呼ばれるメソッドであることを示す setup()
@After 各テストメソッドの実行後に呼ばれるメソッドであることを示す tearDown()
@BeforeClass このテストクラスを呼び出す前に1回だけ実行するメソッドを示す
@AfterClass このテストクラスを呼び出した後に1回だけ実行するメソッドを示す
@Ignore 無視するテストメソッドであることを示す

JUnit3.8 では、テスタークラスを作るために、必死で TestCase を継承して、チマチマとコードを埋めていくということをやっていたけれども、JUnit4.3 ではアノテーションのおかげもあって、かなりラクチンに書けますね。単純なテストケースなら、public なメソッドに @Test アノテーションを付与してあげるだけで、OK。

assert の処理など細かいところは、これから見ていきまっす。でも、static import すれば、3.8 と変わらないように使えそうなので、ムダな学習コストもかからなそう。ふむふむ。

3.8 で言うところのテストスイートを書くのであれば、@SuiteClasses アノテーションを使って以下のような感じで書けばOKっぽい。

@SuiteClasses ( { Sample1Test.class, Sample2Test.class } );
public class AllSampleTests {

}

まあ、でも Eclipse3.2 以降であれば、JUnit4 に対応しているようなので、テストスイートを用意せんでも、テスト用パッケージから実行してしまえば全部できるので、テストケースに集中すればOK。というか、テストスイートの対象テストクラスを @SyuteClasses に全て羅列しなくちゃいけないのは面倒なので、テストのまとめ実行は IDE からやるのがオススメでしょうか。

お疲れさまでした。

PostgreSQL で連番を生成する generate_series

/ db

集合を返す関数 generate_series

今さら知ったんですが、こんな便利な関数があったんですね。PostgreSQL8.0から追加された関数らしく、これを使えば連番やカレンダーテーブルを簡単に作成することができる。うわー、もっと早く知っておきたかった!朝から大興奮!

例えば、1~10までの項番を作成する場合。

SELECT * FROM generate_series(1,10);

generate_series ----------------- 1 2 3 4 5 6 7 8 9 10 (10 rows)

今週の日曜~土曜の一覧を生成する場合。

SELECT
    current_date + s.a AS date
FROM
    generate_series(
        (SELECT 0-extract(dow FROM current_date))::int,
        (SELECT 6-extract(dow FROM current_date))::int
    ) AS s(a);

date ------------ 2008-04-13 2008-04-14 2008-04-15 2008-04-16 2008-04-17 2008-04-18 2008-04-19 (7 rows)

これまでプログラムでごりごり頑張っていた部分のいくつかは、generate_series を使うことで、SQLだけで書けるようになる。プログラムで SQL の足りないところを補おうとすると、非常にややこしや~なことになりがちなので、AP と DB の関係を疎にするアイデアとして、generate_series は良いと思います。PostgreSQL の方言というのが、たまにキズですが…。

厳密な日付の判定

入力された日付情報を String 型で受け取って、Date 型なり Timestamp 型に変換するというのは、よくある話。そして、入力された日付の妥当性を検証するというのも、よくある話。

そんなときは、 Calendar クラスや DateFormat クラスの setLenient メソッドを使えば、らくちんOK。

例えば年月日のフィールドが分かれているケースでは、Calendar クラスを使って次のように妥当性検証ができる。

String year = 2008;
String month = 2;
String day = 30;

try { Calendar c = Calendar.getInstance(); c.setLenient(false); c.set(Integer.parseInt(year), Integer.parseInt(month) - 1, Integer.parseInt(day)); c.getTime(); } catch (IllegalArgumentException e) { // 不正な日付の場合の処理 }

年月日を1フィールドに入力させるケースでは、DateFormat がらくちん。

String date = 2008/2/30

try { DateFormat formatter = new SimpleDateFormat("yyyy/M/d"); formatter.setLenient(false); formatter.parse(date); } catch (ParseException e) { // 不正な日付の場合の処理 }

setLenient(false) にしないと、例えば 2008/2/30 という日付でも例外をスローせず、勝手に 2008/3/1 と解釈してそのまま次の処理を行ってしまう。余計なお世話な気もする。

この話は Java の FAQ のような気がするんだけど、2日連続で方々から質問されたので、メモっときます。

気軽にクラス図が書けるUMLmemo

ちょっとクラス図を描いておきたいなー、というときに使えるUMLエディターが、これ。

UMLmemo

メモという名前のとおり、かなりサクサクと気軽にUMLを描くことができる。シーケンス図は描けないし、複雑なパターンになったりすると使いにくくなってくるけど、「頭にあるものを、データに落とす」というプロセスでは、かなり重宝してます。

実用的なところで言えば、EclipseUML や JUDE を使うんですが、やっぱり重いのが難点。クラス設計って、ひらめきというか、瞬時にわーっアイデアが出てくるから、重いツールだと描画が思考に追いついてこない。

UMLmemo でメモっておいて、EclipseUML で仕上げてコード化していくというのが、今のところのパターンになってます。結構おすすめ。

ただ、一番良い UML エディターは、「手書き」だと思う。

数多のモデリングツールがあれど、アイデアを見える化するのに、手書きに勝るツールはないと思う。UML に限らず、BPMN でも同じ。もちろん最終的なアウトプットを考えたら、各種ツールのメリットは大きくて使わない手はないけど、ラフスケッチは、手が一番。

クラス設計するぞーって言って、いきなり UML エディタを立ち上げるような人もいるんだろうけど、個人的にはちょっと。イラレも、下絵なしで描かないタイプなんで。

jconsole が接続できない

リモートサーバで動いているWebアプリケーションを、jconsole で見てやろうと思ったが、どうしてか接続できない。

開発サーバということで、認証もSSLもなしという最小構成。

-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=8099
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false

これで接続できないとな。認証不要に設定しても、やっぱりユーザ名を指定したりするんだっけか、とか色々と試すもやっぱりムリ。困った。

結論から言うと、サーバの hosts の設定に問題があったみたい。hostname -i で 127.0.0.1 になるとダメらしい。FAQだった。

FAQ - JConsole とリモート管理

ということで、 /etc/hosts を編集してOK。

127.0.0.1	localhost.localdomain
192.168.xxx.xxx	app.localdomain

ちゃんと hostname -i で 192.168.xxx.xxx が返ってきて接続できるようになりますた。開発環境ならでは、という感じはするけど、一応メモ。


最新エントリー
bcp で SQLServer のデータをCSVで書き出す
CSVファイルをPostgreSQLに取り込む方法
JUnit4 を試してみる
PostgreSQL で連番を生成する generate_series
厳密な日付の判定
気軽にクラス図が書けるUMLmemo
jconsole が接続できない
あわせて読みたいブログパーツ