2009年07月03日 DVD on Libretto U100 [長年日記]
_ DVD on Libretto U100
せっかくwritableなDVDドライブが付いているので、Slackware-12.2でDVD Videoを焼いてみたい。
まずmencoderを使って
mencoder dvd://1 -oac lavc -ovc lavc -of mpeg -mpegopts format=dvd -vf scale=720:480 -lavcopts vcodec=mpeg2video:vbitrate=800:acodec=ac3:abitrate=224 -ofps 24 -o movie.mpg
としてDVDからmovie.mpgを作成し、dvdauthor.xmlを以下のように作成して
<dvdauthor>
<vmgm />
<titleset>
<titles>
<pgc>
<vob file="movie.mpg" />
</pgc>
</titles>
</titleset>
</dvdauthor>
dvdauthorコマンドを実行して
rm -fr dvd; dvdauthor -o dvd -x dvdauthor.xml
DVD Videoの構成にオーサリングを行ったところ、
$ ls -alR dvd dvd: 合計 16 drwxr-xr-x 4 m-ito m-ito 4096 2009-07-03 08:46 . drwxr-xr-x 3 m-ito m-ito 4096 2009-07-03 09:15 .. drwxr-xr-x 2 m-ito m-ito 4096 2009-07-03 08:46 AUDIO_TS drwxr-xr-x 2 m-ito m-ito 4096 2009-07-03 08:49 VIDEO_TS dvd/AUDIO_TS: 合計 8 drwxr-xr-x 2 m-ito m-ito 4096 2009-07-03 08:46 . drwxr-xr-x 4 m-ito m-ito 4096 2009-07-03 08:46 .. dvd/VIDEO_TS: 合計 965728 drwxr-xr-x 2 m-ito m-ito 4096 2009-07-03 08:49 . drwxr-xr-x 4 m-ito m-ito 4096 2009-07-03 08:46 .. -rw-r--r-- 1 m-ito m-ito 6144 2009-07-03 08:49 VIDEO_TS.BUP -rw-r--r-- 1 m-ito m-ito 6144 2009-07-03 08:49 VIDEO_TS.IFO -rw-r--r-- 1 m-ito m-ito 22528 2009-07-03 08:49 VTS_01_0.BUP -rw-r--r-- 1 m-ito m-ito 22528 2009-07-03 08:49 VTS_01_0.IFO -rw-r--r-- 1 m-ito m-ito 987860992 2009-07-03 08:49 VTS_01_1.VOB
AUDIO_TSディレクトリ以下が空っぽになっている。何が問題なのか?。
2009年07月04日 DVD-VIDEO焼きスクリプト on Libretto U100 [長年日記]
_ DVD-VIDEO焼きスクリプト on Libretto U100
念願のDVD-VIDEO焼きスクリプト完成。AUDIO_TSディレクトリ以下が空っぽは問題なかった。
dvd2dvd.sh
#! /bin/sh
if [ "X$1" = "X-h" -o "X$1" = "X--help" ]
then
echo "Usage : dvd2dvd.sh [-sp speed] [-rw] [-2] [-s hh:mm:ss] [ -e hh:mm:ss] [-t title] [-c chapter] [-a aspect] [-vb vbitrate] [-ab abitrate] [-f fps] [-al audio_lang] [-sl subtitle_lang]"
echo ""
echo " -sp speed : write power (default 4)"
echo " -rw : DVD-RW"
echo " -2 : 2-pass"
echo " -s start_time : start position time"
echo " -e end_time : pass time"
echo " -t title : title number (default 1)"
echo " -c chapter : chapter (default 1)"
echo " -a aspect : aspect 16/9 or 4/3 (default 16/9)"
echo " -vb vbitrate : video bitrate (kbit) (default 5000)"
echo " -ab abitrate : audio bitrate (kbit) (default 192)"
echo " -f fps : frame per second 30000/1001 or 24000/1001 (default 30000/1001)"
echo " -al audio_lang : audio language (default ja,en)"
echo " -ai audio_id : audio id"
echo " -sl subtitle_lang : subtitle language (default none)"
echo " -si subtitle_id : subtitle id "
exit 0
fi
#
speed="4"
rw=no
pass="1"
start=""
end=""
title="1"
chapter="1"
aspect=16/9
vbitrate=5000
abitrate=192
ofps=30000/1001
alang="ja"
aid=""
slang=""
sid=""
#
while [ $# != 0 ]
do
case $1 in
-sp )
shift
speed="$1"
;;
-rw )
rw=yes
;;
-2 )
pass=2
;;
-s )
shift
start="-ss $1"
;;
-e )
shift
end="-endpos $1"
;;
-t )
shift
title="$1"
;;
-c )
shift
chapter="$1"
;;
-a )
shift
aspect=$1
;;
-vb )
shift
vbitrate="$1"
;;
-ab )
shift
abitrate="$1"
;;
-f )
shift
ofps="$1"
;;
-al )
shift
alang="$1"
;;
-ai )
shift
aid="$1"
;;
-sl )
shift
slang="$1"
;;
-si )
shift
sid="$1"
;;
esac
shift
done
#
if [ "X${alang}" = "X" ]
then
alang_opt=""
else
alang_opt="-alang ${alang}"
fi
#
if [ "X${aid}" = "X" ]
then
aid_opt=""
else
aid_opt="-aid ${aid}"
fi
#
if [ "X${slang}" = "X" ]
then
slang_opt=""
else
slang_opt="-slang ${slang}"
fi
#
if [ "X${sid}" = "X" ]
then
sid_opt=""
else
sid_opt="-sid ${sid}"
fi
#
function menc() {
pass=$1
filename=$2
if [ "X${pass}" = "X0" ]
then
vpass=""
else
vpass="vpass=${pass}:"
fi
mencoder dvd://${title} -chapter ${chapter} \
${start} ${end} \
${alang_opt} ${aid_opt} \
${slang_opt} ${sid_opt} \
-oac lavc \
-ovc lavc \
-of mpeg \
-mpegopts format=dvd:tsaf \
-vf scale=720:480,harddup \
-srate 48000 \
-af lavcresample=48000 \
-lavcopts ${vpass}vcodec=mpeg2video:vrc_buf_size=1835:vrc_maxrate=9800:vbitrate=${vbitrate}:keyint=18:vstrict=0:acodec=ac3:abitrate=${abitrate}:aspect=${aspect} \
-ofps ${ofps} \
-o ${filename}
}
#
if [ "X${pass}" = "X1" ]
then
menc 0 dvd2dvd.mpg.tmp
else
menc 1 /dev/null
menc 2 dvd2dvd.mpg.tmp
fi
#
cat >dvd2dvd.xml.tmp <<_EOF_
<dvdauthor>
<vmgm />
<titleset>
<titles>
<pgc>
<vob file="dvd2dvd.mpg.tmp" chapters="0,5:00,10:00,15:00,20:00,25:00,30:00,35:00,40:00,45:00,50:00,55:00,1:00:00,1:05:00,1:10:00,1:15:00,1:20:00,1:25:00,1:30:00,1:35:00,1:40:00,1:45:00,1:50:00,1:55:00,2:00:00,2:05:00,2:10:00,2:15:00,2:20:00,2:25:00,2:30:00,2:35:00,2:40:00,2:45:00,2:50:00,2:55:00,3:00:00" />
</pgc>
</titles>
</titleset>
</dvdauthor>
_EOF_
dvdauthor -o dvd2dvd.dir.tmp -x dvd2dvd.xml.tmp
#
mkisofs -o dvd2dvd.img.tmp -dvd-video dvd2dvd.dir.tmp/
#
eject /dev/dvd
echo ""
echo ================================================
echo Change to BLANK DVD-R and hit ENTER to continue.
echo ================================================
read
#
if [ "X${rw}" = "Xyes" ]
then
dvdrecord dev=2,0,0 speed=${speed} blank=fast
fi
dvdrecord -v dev=2,0,0 speed=${speed} -dao dvd2dvd.img.tmp
eject /dev/dvd
#
rm -fr dvd2dvd.*.tmp
参考 :
2009年07月05日 キーボードから輝度コントロール等 on Libretto U100 [長年日記]
_ キーボードから輝度コントロール等 on Libretto U100
fnfxdを使うとできるらしい。
インストール
$ tar xvzf fnfx-0.3.tar.gz $ cd fnfx-0.3 $ ./configure && make # make install
後述するfnfxdが何故か/usr/local/etc/fnfx/を見ずに/etc/fnfx/を見てしまうので、シンボリックリンクをはる。
# ln -s /usr/local/etc/fnfx /etc/fnfx
それと(よくわからない)クライアントのfnfxが参照する~/.fnfxrcをサンプルからコピーする。
$ cp /etc/fnfx/fnfxrc_example ~/.fnfxrc
fnfxd(デーモン)をブート時に起動するように設定。
/etc/rc.d/rc.local
if [ -x /usr/local/sbin/fnfxd ]
then
/usr/local/sbin/fnfxd start
fi
東芝ラップトップのACPIモジュールをブート時にロードするように設定。
/etc/rc.d/rc.module
/sbin/modprobe toshiba_acpi
これで、Fn+F6(輝度ダウン)、Fn+F7(輝度アップ)ができるようになる。その他のキーアサインについては、/etc/fnfx/fnfxd.confを参照。
2009年07月06日 myh.no-ip.org(libretto 100) linux-2.4.37.2 Version UP [長年日記]
_ myh.no-ip.org(libretto 100) linux-2.4.37.2 Version UP
サーバ(myh.no-ip.org on Libretto 100)のカーネルをlinux-2.4.37.2にバージョンアップ。すると以前から出ていた
request_module[net-pf-10]: waitpid(3788,...) failed, errno 1
のメッセージが出なくなっていた(^o^)/。さらに、modprobe.oldがゾンビプロセスになってた件も解決していた(^O^)/。
2009年07月10日 Java儂(わし)的解釈によるメモ(JDBC + MySQL編) [長年日記]
_ Java儂(わし)的解釈によるメモ(JDBC + MySQL編)
JavaからDBMS(MySQL)にJDBC経由で接続してみる。例によって用語、用法等は思い込みである部分が見受けられると思うが、御容赦願う。
準備
Slackware-12.xに標準でインストールされるMySQL-5.xをそのまま利用する。
JDBCドライバの取得
mysql-connector-java-5.0.8.tar.gzを取得(http://dev.mysql.com/downloads/connector/j/)
$ tar xvzf mysql-connector-java-5.0.8.tar.gz $ cp mysql-connector-java-5.0.8/mysql-connector-java-5.0.8-bin.jar .
mysql-connector-java-5.0.8-bin.jarをどこかグローバルな場所(例えば/usr/local/jdk/みたいな)に置いて、
CLASSPATH=${CLASSPATH}:/usr/local/jdk/mysql-connector-java-5.0.8-bin.jar; export CLASSPATH
しておくのも良いかも。
データベース領域の初期化
mysqldを起動するに当たって、一度だけ実行する必要がある。
# mysql_install_db --user=mysql
mysqld起動スクリプトの修正
JDBC経由でアクセスするために起動オプションを修正する(/etc/rc.d/rc.mysqld)。
#SKIP="--skip-networking" <-- コメントアウト
MySQLコンフィグファイル設定
デフォルト文字コード、デフォルトストレージエンジンの設定。
標準のストレージエンジンであるMyISAMは速度は早いが、トランザクションがサポートされていない。非標準のストレージエンジンであるInnoDBはMyISAMに比べると速度が劣るがトランザクションをサポートする。
汎用機畑で育った私としてはトランザクションが無い(すなわちcommit、rollbackが無い)のは信じられないので、デフォルトのストレージエンジンをInnoDBに変更する。
# cp /etc/my-small.conf /etc/my.cnf # vi /etc/my.cnf [client] ##default-character-set = utf8 default-character-set = ujis
[mysqld] ##default-character-set = utf8 default-character-set = ujis default-storage-engine=innodb
mysqld起動
# chmod +x /etc/rc.d/rc.mysqld; reboot
MySQL管理者(root)のパスワード設定
# mysqladmin -u root password ROOT-PASSWORD
データベース(jdbctestdb)の作成
# mysql -u root -p Enter password: XXXXXXXXXXXXX <-- ROOT-PASSWORDを入力する mysql> create database jdbctestdb character set ujis; mysql> quit
一般ユーザ(m-ito)にデータベースへのアクセス権を設定
# mysql -u root -p jdbctestdb Enter password: XXXXXXXXXXXXX <-- ROOT-PASSWORDを入力する mysql> grant all on jdbctestdb.* to 'm-ito'@'localhost' identified by 'USER-PASSWORD'; mysql> quit
一般ユーザ用MySQLコンフィグファイル設定
パスワードの設定とデフォルト文字コードの設定。このあたりは必要に応じて...。
$ cp /etc/my-small.conf ~m-ito/.my.cnf $ chmod 600 ~m-ito/.my.cnf $ vi ~m-ito/.my.cnf [client] password = USER-PASSWORD ##default-character-set = utf8 default-character-set = ujis
サンプルプログラム
//
// 「jdbc mysql」テスト
//
// compile : javac -encoding utf-8 jdbc_mysql.java
// run : java -cp .:mysql-connector-java-5.0.8-bin.jar jdbc_mysql
//
//import java.sql.*;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
public class jdbc_mysql {
static Connection conn = null;
static Statement stmt = null;
static PreparedStatement pstmt = null;
static ResultSet rs = null;
static ResultSetMetaData rsmd = null;
public static void main(String[] args) {
try {
//
// JDBC for MySQLのロード
//
Class.forName("com.mysql.jdbc.Driver").newInstance();
System.out.println("JDBCドライバをロードしました。");
//
// データベースへの接続
//
// String url = "jdbc:mysql://localhost/jdbctestdb?useUnicode=true&characterEncoding=SJIS";
String url = "jdbc:mysql://localhost/jdbctestdb?useUnicode=true&characterEncoding=EUC_JP";
conn = DriverManager.getConnection(url, "m-ito", "USER-PASSWORD");
System.out.println("jdbctestdbに接続しました。");
//
// 自動コミット停止(トランザクションの開始)
//
conn.setAutoCommit(false);
System.out.println("自動コミットをOFFにしました。");
//
// SQLステートメントオブジェクト生成
//
stmt = conn.createStatement();
//
// テーブルの削除
//
try {
stmt.executeUpdate("drop table member");
System.out.println("テーブル member を削除しました。");
} catch(Exception e){
System.out.println("テーブル member を削除できませんでした(" + e.getMessage() + ")");
}
//
// テーブルの作成
//
stmt.executeUpdate(
"create table member (" +
"id INT PRIMARY KEY," +
"name VARCHAR(50)," +
"job VARCHAR(50)" +
") engine = innodb"
);
System.out.println("テーブル member を作成しました。");
//
// わざと2重にテーブル作成してみる
//
try {
stmt.executeUpdate(
"create table member (" +
"id INT PRIMARY KEY," +
"name VARCHAR(50)," +
"job VARCHAR(50)" +
")"
);
System.out.println("テーブル member を作成しました(2)。");
} catch(Exception e){
System.out.println("テーブル member を作成できませんでした(2)(" + e.getMessage() + ")");
}
//
// 2次インデックス作成
//
stmt.executeUpdate("create index i_member_name on member(name)");
System.out.println("インデックスを作成しました。");
//
// タプルの追加
//
try {
pstmt = conn.prepareStatement("insert into member (id, name, job) values (?, ?, ?)");
//
// 1件目
//
pstmt.setInt(1, 1);
pstmt.setString(2, "伊藤 太郎");
pstmt.setString(3, "サラリーマン");
pstmt.executeUpdate();
System.out.println("インサートしました。");
//
// 2件目
//
pstmt.setInt(1, 2);
pstmt.setString(2, "山田 太郎");
pstmt.setString(3, "野球選手");
pstmt.executeUpdate();
System.out.println("インサートしました。");
//
// 3件目
//
pstmt.setInt(1, 3);
pstmt.setString(2, "山田 花子");
pstmt.setString(3, "タレント");
pstmt.executeUpdate();
System.out.println("インサートしました。");
//
// わざと3件目をもう一度追加してみる
//
pstmt.setInt(1, 3);
pstmt.setString(2, "山田 花子");
pstmt.setString(3, "タレント");
pstmt.executeUpdate();
System.out.println("インサートしました。");
} catch (Exception e) {
System.out.println("インサートできませんでした(" + e.getMessage() + ")");
}
//
// タプルの検索
//
try {
//
// クエリの実行
//
pstmt = conn.prepareStatement("select * from member where id >= ?");
pstmt.setInt(1, 1);
rs = pstmt.executeQuery();
//
// 1件目の取り出し
//
rs.next();
System.out.println("セレクトしました(id=" +
rs.getInt("id") + ")(name=" +
rs.getString("name") + ")(job=" +
rs.getString("job") + ")。");
//
// 2件目の取り出し
//
rs.next();
System.out.println("セレクトしました(id=" +
rs.getInt("id") + ")(name=" +
rs.getString("name") + ")(job=" +
rs.getString("job") + ")。");
//
// 3件目の取り出し
//
rs.next();
System.out.println("セレクトしました(id=" +
rs.getInt("id") + ")(name=" +
rs.getString("name") + ")(job=" +
rs.getString("job") + ")。");
//
// わざと存在しない4件目を取り出してみる
//
rs.next();
System.out.println("セレクトしました(id=" +
rs.getInt("id") + ")(name=" +
rs.getString("name") + ")(job=" +
rs.getString("job") + ")。");
} catch (Exception e) {
System.out.println("セレクトできませんでした(" + e.getMessage() + ")");
}
//
// タプルの更新
//
try {
//
// 更新ステートメント実行
//
pstmt = conn.prepareStatement("update member set job = ? where name = ?");
pstmt.setString(1, "裁判官");
pstmt.setString(2, "山田 太郎");
pstmt.executeUpdate();
System.out.println("アップデートしました。");
//
// 更新結果を取り出すクエリの実行
//
pstmt = conn.prepareStatement("select * from member where name = ?");
pstmt.setString(1, "山田 太郎");
rs = pstmt.executeQuery();
//
// クエリ結果の取り出し
//
rs.next();
System.out.println("アップデート結果(id=" +
rs.getInt("id") + ")(name=" +
rs.getString("name") + ")(job=" +
rs.getString("job") + ")。");
} catch (Exception e) {
System.out.println("アップデートできませんでした(" + e.getMessage() + ")");
}
//
// タプルの削除
//
try {
//
// 削除ステートメント実行
//
pstmt = conn.prepareStatement("delete from member where name like ?");
pstmt.setString(1, "山田%");
pstmt.executeUpdate();
System.out.println("デリートしました(" + pstmt.getUpdateCount() + "件)。");
//
// 削除後の状態の検索クエリ実行
//
pstmt = conn.prepareStatement("select * from member");
rs = pstmt.executeQuery();
//
// クエリ結果の取り出し
//
while (rs.next()){
System.out.println("デリート結果(id=" +
rs.getInt("id") + ")(name=" +
rs.getString("name") + ")(job=" +
rs.getString("job") + ")。");
}
} catch (Exception e) {
System.out.println("デリートできませんでした(" + e.getMessage() + ")");
}
//
// メタデータの取得
//
try {
//
// メタデータの取得
//
rsmd = rs.getMetaData();
//
// カラム数の取得
//
int numberOfColumns = rsmd.getColumnCount();
System.out.print("メタデータを取得しました(");
for (int i = 1; i <= numberOfColumns; i++) {
//
// カラム名称の取得
//
String name = rsmd.getColumnName (i);
System.out.print(name + "\t");
}
System.out.println(")。");
} catch (Exception e) {
System.out.println("メタデータを取得できませんでした(" + e.getMessage() + ")");
}
//
// コミット(トランザクションの反映)
//
try {
conn.commit();
System.out.println("コミットしました。");
} catch (Exception e) {
System.out.println("コミットできませんでした(" + e.getMessage() + ")");
}
} catch (SQLException e) {
System.out.println("SQLException: " + e.getMessage());
System.out.println("SQLState: " + e.getSQLState());
System.out.println("VendorError: " + e.getErrorCode());
//
// ロールバック(トランザクションの破棄)
//
try {
conn.rollback();
} catch(Exception e2){
System.out.println(e2.getMessage());
}
} catch(Exception e){
System.out.println(e.getMessage());
//
// ロールバック(トランザクションの破棄)
//
try {
conn.rollback();
} catch(Exception e2){
System.out.println(e2.getMessage());
}
}
try {
//
// 検索クエリの結果セットオブジェクトを破棄
//
rs.close();
//
// SQLステートメントオブジェクトを破棄
//
stmt.close();
pstmt.close();
//
// データベースからの切断
//
conn.close();
} catch(Exception e){
System.out.println(e.getMessage());
}
System.out.println("jdbctestdbから切断しました。");
}
}
実行結果
JDBCドライバをロードしました。 jdbctestdbに接続しました。 自動コミットをOFFにしました。 テーブル member を削除しました。 テーブル member を作成しました。 テーブル member を作成できませんでした(2)(Table 'member' already exists) インデックスを作成しました。 インサートしました。 インサートしました。 インサートしました。 インサートできませんでした(Duplicate entry '3' for key 1) セレクトしました(id=1)(name=伊藤 太郎)(job=サラリーマン)。 セレクトしました(id=2)(name=山田 太郎)(job=野球選手)。 セレクトしました(id=3)(name=山田 花子)(job=タレント)。 セレクトできませんでした(After end of result set) アップデートしました。 アップデート結果(id=2)(name=山田 太郎)(job=裁判官)。 デリートしました(2件)。 デリート結果(id=1)(name=伊藤 太郎)(job=サラリーマン)。 メタデータを取得しました(id name job )。 コミットしました。 jdbctestdbから切断しました。
追記
- stmt.executeUpdate(INSERT|DELETE|UPDATE) の戻り値は更新されたタプル数
- stmt.executeUpdate(上記以外の更新系SQL) の戻り値は 0
- エラー発生時は SQLExceptin 発生。getSQLState()にてエラーコードを取得できる。
about Microsoft SQL Server(情報のみ)
Microsoft SQL Server 2005 JDBC Driver
JDBCドライバ(msbase.jar、mssqlserver.jar)を使用した場合(SQLServer2000以前)
Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver");
Connection con = DriverManager.getConnection("jdbc:microsoft:sqlserver://サーバ名:1433","ユーザID","パスワード");
JDBCドライバ(sqljdbc.jar)を使用した場合(SQLServer2005以降)
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
Connection con = DriverManager.getConnection("jdbc:sqlserver://サーバ名:1433","ユーザID","パスワード");
about Oracle(情報のみ)
Class.forName("oracle.jdbc.driver.OracleDriver");
Connection con = DriverManager.getConnection("jdbc:oracle:thin:@サーバ名:1521:OracleSID","ユーザID","パスワード");
OracleSID : tnsnames.ora に記述がある。
2009年07月11日 ruby(1.8.x)儂(わし)的解釈によるメモ(DBI + MySQL編) [長年日記]
_ ruby(1.8.x)儂(わし)的解釈によるメモ(DBI + MySQL編)
rubyからDBMS(MySQL)にDBI経由で接続してみる。例によって用語、用法等は思い込みである部分が見受けられると思うが、御容赦願う。
準備
dbi-0.4.1.tar.gzを取得する(http://rubyforge.org/frs/?group_id=234)。
# tar xvzf dbi-0.4.1.tar.gz # cd dbi-0.4.1/ # gem install dbi # gem install dbd-mysql
もし上記でdbiがうまくインストール出来なかった場合は、
# ruby setup.rb config # ruby setup.rb setup # ruby setup.rb install
を試してみるとよいかも...。
サンプルプログラム
#! /usr/bin/ruby
#
require 'rubygems'
require 'dbi'
#
# データベースへの接続
#
dbh = DBI.connect('DBI:Mysql:dbitestdb', 'm-ito', 'USER-PASSWORD')
puts("データベース(dbitestdb)に接続しました。")
#
# 文字コードの設定(MySQL依存)
#
dbh.do('SET NAMES ujis')
puts("日本語文字コードをujisに設定しました(MySQL依存設定)。")
#
# 自動コミットの停止
#
##dbh.do('SET AutoCommit = 0')
dbh['AutoCommit'] = false
puts("自動コミット停止しました(トランザクションの開始)。")
#
# トランザクション(1)
#
dbh.transaction {|dbh|
#
# テーブルの削除
#
begin
sql = <<SQL
drop table member
SQL
dbh.do(sql)
puts "テーブルの削除に成功しました。"
rescue => e
puts "テーブルの削除に失敗しました(#{e.to_s})。"
end
#
# テーブルの作成(engine = innodbによるストレージエンジンの
# 指定はMySQL依存機能)
#
begin
sql = <<SQL
create table member (
id INT PRIMARY KEY,
name VARCHAR(50),
job VARCHAR(50)
) engine = innodb
SQL
dbh.do(sql)
puts "テーブルの作成に成功しました。"
rescue => e
puts "テーブルの作成に失敗しました(#{e.to_s})。"
end
#
# わざと2重にテーブルを作成してみる
#
begin
sql = <<SQL
create table member (
id INT PRIMARY KEY,
name VARCHAR(50),
job VARCHAR(50)
)
SQL
dbh.do(sql)
puts "テーブルの作成に成功しました(2)。"
rescue => e
puts "テーブルの作成に失敗しました(2)(#{e.to_s})。"
end
#
# インデックスの作成
#
sql = <<SQL
create index i_member_name on member(name)
SQL
dbh.do(sql)
puts "インデックスの作成に成功しました。"
}
#
# トランザクション(2)
#
dbh.transaction {|dbh|
#
# データの追加
#
sql = <<SQL
insert into member (id, name, job) values (?, ?, ?)
SQL
sth = dbh.prepare(sql)
sth.execute(1, '伊藤 太郎', 'サラリーマン')
puts "インサートに成功しました。"
sth.execute(2, '山田 太郎', '野球選手')
puts "インサートに成功しました。"
sth.execute(3, '山田 花子', 'タレント')
puts "インサートに成功しました。"
#
# わざと2重キーで登録してみる
#
begin
sth.execute(3, '山田 花子', 'タレント')
puts "インサートに成功しました。"
rescue => e
puts "インサートに失敗しました(#{e.to_s})。"
end
sth.finish
}
#
# データの検索
#
sql = <<SQL
select * from member where id >= ?
SQL
sth = dbh.prepare(sql)
sth.execute(1)
while (row = sth.fetch)
puts "セレクトに成功しました(id=#{row['id']})(name=#{row['name']})(job=#{row['job']})"
end
sth.finish
#
# トランザクション(3)
#
dbh.transaction {|dbh|
#
# データの更新
#
sql = <<SQL
update member set job = ? where name = ?
SQL
sth = dbh.prepare(sql)
sth.execute('裁判官', '山田 太郎')
puts ("アップデートに成功しました。")
sth.finish
}
#
# 更新結果の確認
#
sql = <<SQL
select * from member where name = ?
SQL
sth = dbh.prepare(sql)
sth.execute('山田 太郎')
while (row = sth.fetch)
puts "アップデートの確認(id=#{row['id']})(name=#{row['name']})(job=#{row['job']})"
end
sth.finish
#
# トランザクション(4)
#
dbh.transaction {|dbh|
#
# データの削除
#
sql = <<SQL
delete from member where name like ?
SQL
sth = dbh.prepare(sql)
sth.execute('山田%')
puts ("デリートに成功しました。")
sth.finish
}
#
# 削除の確認
#
sql = <<SQL
select * from member
SQL
sth = dbh.prepare(sql)
sth.execute()
while (row = sth.fetch)
puts "デリートの確認(id=#{row['id']})(name=#{row['name']})(job=#{row['job']})"
end
sth.finish
#
# メタデータの取得
#
sql = <<SQL
select * from member
SQL
sth = dbh.prepare(sql)
sth.execute()
puts "メタデータ カラム数=#{sth.column_names.size}"
print "メタデータ カラム名="
sth.column_names.each {|name|
print "#{name}\t"
}
puts ""
#
sth.column_info.each_with_index {|info, i|
print "項番 = #{i} / "
print "カラム名 = #{info.name} / "
print "精度 = #{info.precision} / "
print "スケール = #{info.scale}\n"
}
sth.finish
#
# (手動で)のコミット(またはロールバック)の実行
#
#dbh.rollback
#puts "ロールバックしました。"
dbh.commit
puts "コミットしました。"
#
# データベースからの切断
#
dbh.disconnect
puts("データベース(dbitestdb)から切断しました。")
実行結果
データベース(dbitestdb)に接続しました。 日本語文字コードをujisに設定しました(MySQL依存設定)。 自動コミット停止しました(トランザクションの開始)。 テーブルの削除に成功しました。 テーブルの作成に成功しました。 テーブルの作成に失敗しました(2)(Table 'member' already exists)。 インデックスの作成に成功しました。 インサートに成功しました。 インサートに成功しました。 インサートに成功しました。 インサートに失敗しました(Duplicate entry '3' for key 1)。 セレクトに成功しました(id=1)(name=伊藤 太郎)(job=サラリーマン) セレクトに成功しました(id=2)(name=山田 太郎)(job=野球選手) セレクトに成功しました(id=3)(name=山田 花子)(job=タレント) アップデートに成功しました。 アップデートの確認(id=2)(name=山田 太郎)(job=裁判官) デリートに成功しました。 デリートの確認(id=1)(name=伊藤 太郎)(job=サラリーマン) メタデータ カラム数=3 メタデータ カラム名=id name job 項番 = 0 / カラム名 = id / 精度 = 11 / スケール = 0 項番 = 1 / カラム名 = name / 精度 = 150 / スケール = 0 項番 = 2 / カラム名 = job / 精度 = 150 / スケール = 0 コミットしました。 データベース(dbitestdb)から切断しました。
_ googleearth on Libretto U100(Slackware-12.2)
googleearthを入れてみた。十分な速度で動いてくれた。ただし、日本語メニューが化けている。
どうやらパッケージに同梱されている libQt*.so.4 が国際化対応でビルドされた物ではないようだ。そこで qt-x11-opensource-src-4.5.2.tar.gzを取得して ./configure && make && make install でインストールし、 /etc/ld.so.conf に /usr/local/Trolltech/Qt-4.5.2/lib を追加して ldconfig した後、念のために ~/google-earth/配下にある、
$ ls -al google-earth/libQt* -rwxr-xr-x 1 m-ito m-ito 2244156 2009-07-09 20:38 google-earth/libQtCore.so.4 -rwxr-xr-x 1 m-ito m-ito 7305864 2009-07-09 20:38 google-earth/libQtGui.so.4 -rwxr-xr-x 1 m-ito m-ito 774340 2009-07-09 20:38 google-earth/libQtNetwork.so.4 -rwxr-xr-x 1 m-ito m-ito 7265852 2009-07-09 20:38 google-earth/libQtWebKit.so.4
を削除するなり、リネームするなりして参照されないようにする。
これで無事、日本語メニューも出るようになった。
2009年07月14日 Kernel Version UP 2.6.27.7 to 2.6.29.6 on Slackware-12.2 [長年日記]
_ Kernel Version UP 2.6.27.7 to 2.6.29.6 on Slackware-12.2
Libretto U100(Slackware-12.2)の無線LAN(ath5k Atheros AR2414)の調子があまり良くない。接続ができないわけでは無いけれども、速度が異常に遅い。/var/log/syslogに以下のメッセージが連続して記録されている。
Jul 13 04:55:31 lib190 kernel: ath5k phy0: noise floor calibration timeout (2462MHz)
上記のメッセージ(kernel: ath5k phy0: noise floor calibration timeout)で検索してみると、同様の報告が結構あって、カーネルのバージョンをアップすれば改善する様子。
そこで現行の 2.6.27.7 から 2.6.29.6 へバージョンアップすることにする。現時点での最新カーネルは 2.6.30.1 なのだが、Slackware-currentが 2.6.29.5 だったので、同系列の最新版を採用することにした。コンフィグ(config-huge-smp-2.6.29.5-smp)もSlackware-currentのものを利用できるし、安心。
# cd /usr/src # rm linux # tar xvjf linux-2.6.29.6.tar.bz2 # ln -s linux-2.6.29.6 linux # cd linux # make mrproper # cp /anywhere/config-huge-smp-2.6.29.5-smp .config # make oldconfig # make menuconfig <-- CPU TYPE を Pentium-M に変更 # make # make modules_install # make install
Cahngesを確認すると、e2fsprogs-1.41.4以上を求められているが、Slackware-12.2のは1.41.3だったので、これもバージョンアップする。Slackware-currentのe2fsprogsのビルドスクリプトを参考にして、
# tar xvzf e2fsprogs-1.41.8.tar.gz
# cd e2fsprogs-1.41.8
# VERSION=1.41.8
# ./configure \
--prefix=/usr \
--libdir=/lib \
--bindir=/usr/bin \
--includedir=/usr/include \
--datadir=/usr/share \
--mandir=/usr/man \
--infodir=/usr/info \
--docdir=/usr/doc/e2fsprogs-$VERSION \
--enable-elf-shlibs \
--enable-dynamic-e2fsck \
--enable-libblkid \
--disable-uuidd
# make
# make install
# make install-libs
以上で、カーネルバージョンアップ+αの作業完了。あとはこれで無線LANが安定してくれれば...。
_ X.orgで日本語フォントが中国っぽくなる件
# cd /etc/fonts/conf.d # mv 44-wqy-zenhei.conf 44-wqy-zenhei.conf.REMOVED
にて解決。
2009年07月19日 libretto100(myh.no-ip.org server) harddisk crash! [長年日記]
_ libretto100(myh.no-ip.org server) harddisk crash!
4月にディスク交換したmyh.no-ip.orgのサーバであったが、見事にディスククラッシュ。
前日に異音を発したのでとりあえず再起動を行い、異音が消えたため即座にバックアップを取得し、そのまま継続運用していた。
翌日、仕事から帰ってみるとフリーズ状態。再起動して稼働することは確認するも、その後出かける用事があったので念のために(発熱で火災でも起こすと困るので)シャットダウンして出かける。
帰宅して電源入れるも、ハードディスクが異音を起てて起動せず。完全にクラッシュ状態となる。
はぁ〜...
予備のハードディスクにバックアップから戻し、復旧。
_ 教訓:ヤフオクの(中古)ハードディスクは信用できない。
2009年07月25日 firefox-3.0.12, firefox-3.5.1 on Slackware-12.2 [長年日記]
_ firefox-3.0.12, firefox-3.5.1 on Slackware-12.2
.mozconfig
. $topsrcdir/browser/config/mozconfig ac_add_options --disable-debug ac_add_options --enable-optimize ac_add_options --enable-default-toolkit=cairo-gtk2
build
nice make -f client.mk build nice make package
2009年07月30日 MySQL-5.x 儂(わし)的解釈によるメモ(運用編) [長年日記]
_ MySQL-5.x 儂(わし)的解釈によるメモ(運用編)
Slackware-12.xに標準でインストールされるMySQL-5.xをそのまま運用する際に 最低限必要と思われる知識に関するメモ。いろんなページの切り貼り。
Java儂(わし)的解釈によるメモ(JDBC + MySQL編)と若干かぶってるのは御勘弁を。
前提条件
- MySQLの管理者 root
- MySQLの一般ユーザ兼管理者 m-ito
データベース領域の初期化
mysqldを起動するに当たって、一度だけ実行する必要がある。
# mysql_install_db --user=mysql
mysqld起動スクリプトの修正
ネットワーク越しにアクセス(JDBC経由も含む)するために起動オプションを修正する (/etc/rc.d/rc.mysqld)。
#SKIP="--skip-networking" <-- コメントアウト
MySQLコンフィグファイル設定
デフォルト文字コード、デフォルトストレージエンジンの設定。
標準のストレージエンジンであるMyISAMは速度は早いが、トランザクションが サポートされていない。非標準のストレージエンジンであるInnoDBはMyISAMに 比べると速度が劣るがトランザクションをサポートする。
汎用機畑で育った私としてはトランザクションが無い(すなわちcommit、 rollbackが無い)のは信じられないので、デフォルトのストレージエンジンを InnoDBに変更する。また、クライアント、サーバともにデフォルトの文字コー ドをujisとする。最近はutf8が主流になりつつあるそうですが...。
# cp /etc/my-small.conf /etc/my.cnf # vi /etc/my.cnf
[client] ##default-character-set = utf8 default-character-set = ujis [mysqld] ##default-character-set = utf8 default-character-set = ujis default-storage-engine=innodb
mysqld起動
# chmod +x /etc/rc.d/rc.mysqld; reboot
MySQL管理者(root)のパスワード設定
$ mysqladmin -u root password ROOT-PASSWORD
データベース(testdb)の作成
$ mysql -u root -p Enter password: XXXXXXXXXXXXX <-- ROOT-PASSWORDを入力する mysql> create database testdb character set ujis; mysql> quit
一般ユーザ(m-ito)を作成
$ mysql -u root -p Enter password: XXXXXXXXXXXXX <-- ROOT-PASSWORDを入力する mysql> create user 'm-ito'@'localhost' identified by 'USER-PASSWORD'; mysql> quit
一般ユーザ(m-ito)にデータベースへのアクセス権を設定
$ mysql -u root -p testdb Enter password: XXXXXXXXXXXXX <-- ROOT-PASSWORDを入力する mysql> grant all on testdb.* to 'm-ito'@'localhost' identified by 'USER-PASSWORD'; mysql> quit
一般ユーザ用MySQLコンフィグファイル設定
パスワードの設定とデフォルト文字コードの設定。このあたりは必要に応じ て...。
$ cp /etc/my-small.conf ~m-ito/.my.cnf $ chmod 600 ~m-ito/.my.cnf $ vi ~m-ito/.my.cnf
[client] password = USER-PASSWORD ##default-character-set = utf8 default-character-set = ujis
データベース、テーブル情報表示
$ mysqlshow -u m-ito -p testdb HogeTable
データベースのダンプ出力
$ msql -u root -p testdb LOCK TABLES HogeTable READ; CTRL-Z
$ mysqldump -u m-ito -p testdb HogeTable $ mysqldump -u m-ito -p --databases testdb $ mysqldump -u m-ito -p --all-databases
$ fg UNLOCK TABLES;
ユーザ管理
$ mysql -u root -p
権限の種類
- ALL : すべての権限。
- ALTER : ALTER TABLE構文が実行できる権限。
- CREATE : データベースとテーブルの作成が行える権限。
- DROP : データベースとテーブルの削除が行える権限。
- FILE : LOAD DATA構文とSELECT 〜 INTO OUTFILE構文を実行できる権限。
- PROCESS : mysqladminコマンドのprocesslistとkill命令を実行できる権限。
- RELOAD : mysqladminコマンドのreload, refresh, flush-privileges, flush-hosts, flush-logs, flush-tables命令を実行できる権限。
- SHUTDOWN : mysqladminコマンドのshutdown命令を実行できる権限。
- DELETE : DELETE構文を実行できる権限。
- INSERT : INSERT構文を実行できる権限。
- SELECT : SELECT構文を実行できる権限。
- UPDATE : UPDATE構文を実行できる権限。
- INDEX : インデックスの作成と削除が行える権限。
- REFERENCES : テーブルのリファレンスが参照できる権限。
- USAGE : すべての権限がない。
管理者の追加
GRANT ALL ON *.* TO 'm-ito'@'%' IDENTIFIED BY 'USER-PASSWORD' WITH GRANT OPTION; GRANT ALL ON *.* TO 'm-ito'@'localhost' IDENTIFIED BY 'USER-PASSWORD' WITH GRANT OPTION; FLUSH PRIVILEGES;
一般ユーザの追加
GRANT SELECT,INSERT,UPDATE,DELETE ON testdb.* TO 'm-ito'@'localhost' IDENTIFIED BY 'USER-PASSWORD'; FLUSH PRIVILEGES;
ユーザ権限の削除
REVOKE ALL ON testdb.* FROM 'm-ito'; FLUSH PRIVILEGES;
ユーザの削除
REVOKEにて全ての権限を削除後
DROP USER 'm-ito'; FLUSH PRIVILEGES;
ユーザの権限確認
SELECT * FROM mysql.user WHERE User='m-ito';
データベースの削除
mysql -u root -p DROP DATABASE testdb;
パスワードの設定
mysql -u root -p
SET PASSWORD FOR 'm-ito'@'%' = PASSWORD('USER-PASSWORD');
CSVファイルの取り込み
mysql -u root -p LOCK TABLES HogeTable WRITE; LOAD DATA INFILE "Hoge.csv" INTO TABLE HogeTable FIELDS TERMINATED BY ',' ENCLOSED BY '"'; UNLOCK TABLES;
- フィールド区切り文字のデフォルトは「タブ」。
- 文字列囲み文字のデフォルトは「無し」。
CSVファイルへの書き出し
mysql -u root -p LOCK TABLES HogeTable READ; SELECT * FROM HogeTable INTO OUTFILE "Hoge.csv" FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'; UNLOCK TABLES;
- フィールド区切り文字のデフォルトは「タブ」。
- 文字列囲み文字のデフォルトは「無し」。
_ BIND 9の脆弱性について
BIND 9にてDynamic DNS機能に関して脆弱性が報告されている。DoSの対称になってしまうとのこと。
JVNVU#725188 ISC BIND 9 におけるサービス運用妨害 (DoS) の脆弱性
早速、libretto100(myh.no-ip.org)のbindもバージョンアップ。
2009年07月31日 Java儂(わし)的解釈によるメモ(JDBC + Microsoft SQL Server 2005 Express Edition編) [長年日記]
_ Java儂(わし)的解釈によるメモ(JDBC + Microsoft SQL Server 2005 Express Edition編)
Windowsの事も知らんぷりできない状況になりつつある中、Microsoft SQL Server 2005 Express Editionという無償で使える MS SQL Serverが有る事を知り、早速試してみた。
基本的にはJava儂(わし)的解釈によるメモ(JDBC + MySQL編)の内容と大差無いが、やはり多少の方言と言うか違いは存在していた。
Windows機(IP=192.168.0.1)側にインストールする物
- Microsoft .NET Framework Version 2.0 再頒布可能パッケージ (x86)
- MS SQL Server 2005 Express edition インストールのポイント
- 「機能の選択」において、とりあえず全コンポーネントを選択する。
- 「認証モード」において、混合モードを選択する。また管理者(sa)のパスワードも設定する。
- インストール完了後、スタートメニューより
- 「プログラム」->「Microsoft SQL Server 2005」->「構成ツール」->「SQL Server Configuration Manager」を起動し
- 「SQL Server 2005 ネットワークの構成」->「SQLEXPRESSのプロトコル」->「TCP/IP」->「プロパティ」->「IPアドレス」->「TCPポート」に「1433」を設定する。その後、上記の「TCP/IP」を「有効化」する。
- 「SQL Server 2005 のサービス」->「SQL Server(SQLEXPRESS)」->「再起動」を行う。
以上でサーバが起動する。
- sqlcmd.exe(Windows側ツール)
sqlcmd.exeはWindows側でデータベースにアクセスするためのクライアント(コマンドライン版)。
インスタンス名はSQLExpressに固定。
ところでインスタンスてなんじゃという話だが、1個のインスタンスが1個のリスナーポートに対応していて、つまりこれが1個のデータベース(この中に多数のテーブルを抱える)サーバプロセスということらしい。(データベースはCREATE DATABASE testdb
で作成する...)
sqlcmd -? ヘルプ表示
sqlcmd -U sa -P SA-PASSWORD -S localhost\SQLExpress 1> SQL命令文 2> GO 3> EXIT
sqlcmd -U sa -P SA-PASSWORD -S localhost\SQLExpress -s "," -W -i Hoge.sql
- その他よく分からないが有れば多分便利なモノたち
クライアント側(Linux or Windows)にインストールする物
Microsoft SQL Server JDBC Driver 2.0内のsqljdbc4.jarをCLASSPATHに追加するか、実行時に
java -cp /somewhere/sqljdbc4.jar HogeHoge
の様に指定する。
サンプルプログラム
//
// 「jdbc mssql」テスト
//
// compile : javac -encoding utf-8 jdbc_mssql.java
// run : java -cp .:sqljdbc4.jar jdbc_mssql
//
//import java.sql.*;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
public class jdbc_mssql {
static Connection conn = null;
static Statement stmt = null;
static PreparedStatement pstmt = null;
static ResultSet rs = null;
static ResultSetMetaData rsmd = null;
public static void main(String[] args) {
try {
//
// JDBC for MS SQL Serverのロード
//
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver").newInstance();
System.out.println("JDBCドライバをロードしました。");
//
// データベースへの接続
//
// String url = "jdbc:sqlserver://192.168.0.1:1433";
// conn = DriverManager.getConnection(url, "sa", "SA-PASSWORD");
String url = "jdbc:sqlserver://192.168.0.1:1433;databaseName=testdb;user=sa;password=SA-PASSWORD;";
conn = DriverManager.getConnection(url);
System.out.println("jdbc:sqlserver://192.168.0.1:1433に接続しました。");
//
// 自動コミット有効
//
// 自動コミットを有効にしないと create index で、テーブル member を見つけられずに
// 例外が発生する。MS SQLServer特有の現象か?。
//
conn.setAutoCommit(true);
System.out.println("自動コミットをONにしました。");
//
// SQLステートメントオブジェクト生成
//
stmt = conn.createStatement();
//
// テーブルの削除
//
try {
stmt.executeUpdate("drop table member");
System.out.println("テーブル member を削除しました。");
} catch(Exception e){
System.out.println("テーブル member を削除できませんでした(" + e.getMessage() + ")");
}
//
// テーブルの作成
//
stmt.executeUpdate(
"create table member (" +
"id INT PRIMARY KEY," +
"name VARCHAR(50)," +
"job VARCHAR(50)" +
")"
);
System.out.println("テーブル member を作成しました。");
//
// わざと2重にテーブル作成してみる
//
try {
stmt.executeUpdate(
"create table member (" +
"id INT PRIMARY KEY," +
"name VARCHAR(50)," +
"job VARCHAR(50)" +
")"
);
System.out.println("テーブル member を作成しました(2)。");
} catch(Exception e){
System.out.println("テーブル member を作成できませんでした(2)(" + e.getMessage() + ")");
}
//
// 2次インデックス作成
//
stmt.executeUpdate("create index i_member_name on member(name)");
System.out.println("インデックスを作成しました。");
//
// 自動コミット無効
//
conn.setAutoCommit(false);
System.out.println("自動コミットをOFFにしました(トランザクション開始)。");
//
// タプルの追加
//
try {
pstmt = conn.prepareStatement("insert into member (id, name, job) values (?, ?, ?)");
//
// 1件目
//
pstmt.setInt(1, 1);
pstmt.setString(2, "伊藤 太郎");
pstmt.setString(3, "サラリーマン");
pstmt.executeUpdate();
System.out.println("インサートしました。");
//
// 2件目
//
pstmt.setInt(1, 2);
pstmt.setString(2, "山田 太郎");
pstmt.setString(3, "野球選手");
pstmt.executeUpdate();
System.out.println("インサートしました。");
//
// 3件目
//
pstmt.setInt(1, 3);
pstmt.setString(2, "山田 花子");
pstmt.setString(3, "タレント");
pstmt.executeUpdate();
System.out.println("インサートしました。");
//
// わざと3件目をもう一度追加してみる
//
pstmt.setInt(1, 3);
pstmt.setString(2, "山田 花子");
pstmt.setString(3, "タレント");
pstmt.executeUpdate();
System.out.println("インサートしました。");
} catch (Exception e) {
System.out.println("インサートできませんでした(" + e.getMessage() + ")");
}
//
// タプルの検索
//
try {
//
// クエリの実行
//
pstmt = conn.prepareStatement("select * from member where id >= ?");
pstmt.setInt(1, 1);
rs = pstmt.executeQuery();
//
// 1件目の取り出し
//
rs.next();
System.out.println("セレクトしました(id=" +
rs.getInt("id") + ")(name=" +
rs.getString("name") + ")(job=" +
rs.getString("job") + ")。");
//
// 2件目の取り出し
//
rs.next();
System.out.println("セレクトしました(id=" +
rs.getInt("id") + ")(name=" +
rs.getString("name") + ")(job=" +
rs.getString("job") + ")。");
//
// 3件目の取り出し
//
rs.next();
System.out.println("セレクトしました(id=" +
rs.getInt("id") + ")(name=" +
rs.getString("name") + ")(job=" +
rs.getString("job") + ")。");
//
// わざと存在しない4件目を取り出してみる
//
rs.next();
System.out.println("セレクトしました(id=" +
rs.getInt("id") + ")(name=" +
rs.getString("name") + ")(job=" +
rs.getString("job") + ")。");
} catch (Exception e) {
System.out.println("セレクトできませんでした(" + e.getMessage() + ")");
}
//
// タプルの更新
//
try {
//
// 更新ステートメント実行
//
pstmt = conn.prepareStatement("update member set job = ? where name = ?");
pstmt.setString(1, "裁判官");
pstmt.setString(2, "山田 太郎");
pstmt.executeUpdate();
System.out.println("アップデートしました。");
//
// 更新結果を取り出すクエリの実行
//
pstmt = conn.prepareStatement("select * from member where name = ?");
pstmt.setString(1, "山田 太郎");
rs = pstmt.executeQuery();
//
// クエリ結果の取り出し
//
rs.next();
System.out.println("アップデート結果(id=" +
rs.getInt("id") + ")(name=" +
rs.getString("name") + ")(job=" +
rs.getString("job") + ")。");
} catch (Exception e) {
System.out.println("アップデートできませんでした(" + e.getMessage() + ")");
}
//
// タプルの削除
//
try {
//
// 削除ステートメント実行
//
pstmt = conn.prepareStatement("delete from member where name like ?");
pstmt.setString(1, "山田%");
pstmt.executeUpdate();
System.out.println("デリートしました(" + pstmt.getUpdateCount() + "件)。");
//
// 削除後の状態の検索クエリ実行
//
pstmt = conn.prepareStatement("select * from member");
rs = pstmt.executeQuery();
//
// クエリ結果の取り出し
//
while (rs.next()){
System.out.println("デリート結果(id=" +
rs.getInt("id") + ")(name=" +
rs.getString("name") + ")(job=" +
rs.getString("job") + ")。");
}
} catch (Exception e) {
System.out.println("デリートできませんでした(" + e.getMessage() + ")");
}
//
// メタデータの取得
//
try {
//
// メタデータの取得
//
rsmd = rs.getMetaData();
//
// カラム数の取得
//
int numberOfColumns = rsmd.getColumnCount();
System.out.print("メタデータを取得しました(");
for (int i = 1; i <= numberOfColumns; i++) {
//
// カラム名称の取得
//
String name = rsmd.getColumnName (i);
System.out.print(name + "\t");
}
System.out.println(")。");
} catch (Exception e) {
System.out.println("メタデータを取得できませんでした(" + e.getMessage() + ")");
}
//
// コミット(トランザクションの反映)
//
try {
conn.commit();
System.out.println("コミットしました。");
} catch (Exception e) {
System.out.println("コミットできませんでした(" + e.getMessage() + ")");
}
} catch (SQLException e) {
System.out.println("SQLException: " + e.getMessage());
System.out.println("SQLState: " + e.getSQLState());
System.out.println("VendorError: " + e.getErrorCode());
//
// ロールバック(トランザクションの破棄)
//
try {
conn.rollback();
} catch(Exception e2){
System.out.println(e2.getMessage());
}
} catch(Exception e){
System.out.println(e.getMessage());
//
// ロールバック(トランザクションの破棄)
//
try {
conn.rollback();
} catch(Exception e2){
System.out.println(e2.getMessage());
}
}
try {
//
// 検索クエリの結果セットオブジェクトを破棄
//
rs.close();
//
// SQLステートメントオブジェクトを破棄
//
stmt.close();
pstmt.close();
//
// データベースからの切断
//
conn.close();
} catch(Exception e){
System.out.println(e.getMessage());
}
System.out.println("mssqlserverから切断しました。");
}
}
実行結果
JDBCドライバをロードしました。 jdbc:sqlserver://192.168.0.1:1433に接続しました。 自動コミットをONにしました。 テーブル member を削除しました。 テーブル member を作成しました。 テーブル member を作成できませんでした(2)(データベースに 'member' という名前のオブジェクトが既に存在します。) インデックスを作成しました。 自動コミットをOFFにしました(トランザクション開始)。 インサートしました。 インサートしました。 インサートしました。 インサートできませんでした(制約 'PK__member__2E3BD7D3' の PRIMARY KEY 違反。オブジェクト 'dbo.member' には重複したキーを挿入できません。) セレクトしました(id=1)(name=伊藤 太郎)(job=サラリーマン)。 セレクトしました(id=2)(name=山田 太郎)(job=野球選手)。 セレクトしました(id=3)(name=山田 花子)(job=タレント)。 セレクトできませんでした(ResultSet に現在の行がありません。) アップデートしました。 アップデート結果(id=2)(name=山田 太郎)(job=裁判官)。 デリートしました(2件)。 デリート結果(id=1)(name=伊藤 太郎)(job=サラリーマン)。 メタデータを取得しました(id name job )。 コミットしました。 mssqlserverから切断しました。
追記
- stmt.executeUpdate(INSERT|DELETE|UPDATE) の戻り値は更新されたタプル数
- stmt.executeUpdate(上記以外の更新系SQL) の戻り値は 0
- エラー発生時は SQLExceptin 発生。getSQLState()にてエラーコードを取得できる。
MySQLとの違い
最初からAutoCommit=falseにしていると、create indexでテーブルが見つけられずに例外が発生した。create tableの直後に明示的にcommitを発行してもダメで、結局create indexまではAutoCommit=trueで実行し、それ以降をAutoCommit=falseで実行することで(無理矢理)解決した。
ショック
- Microsoft SQL Server 2005 Express Edition with Advanced Services(Express Edition + Management Studio Express)というのが有ったんだね。
- さらに新しいMicrosoft SQL Server 2008 Expressというのも有ったんだね...。
一応、サーバをSQL Server 2008 Express with Advanced Servicesに変えても、上記のサンプルは動いた。