DB2 環境構築Knowleadge

■DB作成

CREATE DATABASE database-name USING CODESET IBM-943 TERRITORY JP COLLATE USING IDENTITY

■権限修正

UPDATE DBM CFG USING CATALOG_NOAUTH YES

■スキーマ作成

CREATE SCHEMA schema-name

■テーブルスペースのサイズを調べる方法

LIST TABLESPACE CONTAINERS FOR tablespace-id SHOW DETAIL

db2 => LIST TABLESPACE CONTAINERS FOR 3 show detail

表スペースの表スペース・コンテナー 3

コンテナー ID = 0

名前 = path\tablespace-name

タイプ = ファイル

合計ページ数 = 40960

使用できるページ数 = 40928

アクセス可能 = はい

■テーブルスペースのページサイズを調べる方法

SELECT CHAR(TBSP_NAME,20) TBSP_NAME, TBSP_CONTENT_TYPE, TBSP_PAGE_SIZE FROM SYSIBMADM.SNAPTBSP

■テーブルスペースのページサイズを指定する方法

CREATE BUFFERPOOL tablespace-name SIZE 128 PAGESIZE 8K

CREATE TABLESPACE tablespace-name PAGESIZE 8K MANAGED BY DATABASE USING ( FILE ‘path\tablespace-name ‘ 40960) BUFFERPOOL tablespace-name

■既存のテーブルスペースのページサイズを変更する方法

CREATE TABLESPACE tablespace-name BUFFERPOOL bufferpool-name

DB2 SqlIntegrityConstraintViolationException SQLCODE=-407, SQLSTATE=23502を調べる方法

SqlIntegrityConstraintViolationException

SQLCODE=-407, SQLSTATE=23502

テーブルスペースID、テーブルID、列NoがExceptionの中に表示されるので、下記SQLを実行すれば名称がわかります。
Exceptionも名前で表示してくれればいいのにね。
IDで把握している人いないでしょw

select C.tabschema, C.tabname, C.colname
from syscat.tables as T,
syscat.columns as C
where T.tbspaceid = ''
and T.tableid = ''
and C.colno = ''
and C.tabschema = T.tabschema
and C.tabname = T.tabname
for read only;

DB2で件数指定してSELECTする方法

菱田直哉
沢山データがあるデータで、最初の10件を取得するにはどうしたらいいの?

モリー
それは「FETCH FIRST 10 ROWS ONLY」だね。

Select
*
from T_DUMMY
FETCH FIRST 10 ROWS ONLY
FOR READ ONLY;

菱田直哉
なるほど。これで先頭10件が取れるのか。。。
菱田直哉
例えば、100~200件が取りたい場合は?
モリー
それは、取りたい順序を指定する必要があるから、「ROWNUMBER()」を使うといいよ。

Select
*
from
(
Select
RowNumBer() Over(Order by A_NUM) as R_NUM
, DATA
FROM T_DUMMY
)
Where
R_NUM BETWEEN 100 And 200
FOR READ ONLY;

菱田直哉
A_NUMでソートされた100~200目のレコードが取得できたね!
菱田直哉
じゃあ、最後から10行は?
モリー
それは「FETCH LAST 10 ROWS ONLY」だね。

Select
*
from T_DUMMY
FETCH LAST 10 ROWS ONLY
FOR READ ONLY;

菱田直哉
最後の10行も取れるんだね!
モリー
そうなんだよ。これからデータを取得する場合には活用してね!

SQLで特定の情報のみを検索する方法 Where句

データベース検索中。。。

菱田直哉
う~ん。

モリー
なにを悩んでいるの?

菱田直哉
テーブルの全検索は覚えたんだけど、レコードが多すぎて見つからないんだ。

モリー
そんな時は、欲しい情報のキーを意識するといいよ。

菱田直哉
キー?

モリー
例えば、従業員だったら社員番号とか、一意になるものとかが良いね。

菱田直哉
なるほど、じゃあ、例えば社員1000人の会社で、社員番号500番の情報を知りたい場合はどうするの?

菱田直哉
全部検索すると500行目を見るしかないもんね。。。

モリー
そういう時は、Where句(ウェア句)を使うんだよ。

菱田直哉
Where句?

モリー
まず、全部検索する方法は覚えているよね?

菱田直哉
うん。

Select * from T_EMP;

モリー
そう。社員テーブルから全部のカラムを呼び出しているね。

モリー
そこにどんな情報を書けばいいと思う?

菱田直哉
社員番号が500番のレコードだけってことかな。

モリー
そう。それがWhere句。社員番号がNUMだとすると、こうなるよ。

Select * from T_EMP Where NUM = 500;

菱田直哉
Whereで条件を指定するってことだね!

モリー
わかってきたね。これで悩まなくて済むかな?

菱田直哉
今のところは大丈夫!ありがとう!

条件を指定するのは Where です。
500以上は  NUM >= 500
500より上は NUM > 500
500だけは  NUM = 500
500以下は  NUM <= 500
500より下は NUM < 500

文字列なんかはシングルクオーテーションをつけて
NUM = ‘500’
としましょう。

菱田直哉
ちょっとSQLを使うなら、充分な知識だね!

DB2 テーブルをロックせずにSELECTする方法 with ur;

菱田直哉
DB2でSELECTするとき、「with ur」を必ずつけろって言われたんだけどなんで?

モリー
それは、コミット前のものも確認してねってことじゃない?

菱田直哉
なんか、ロックがどうのこうのって言ってたよ。何も付けないSELECT文じゃダメなの?

モリー
ダメなときと大丈夫なときがあるね。

インデックスがあるなしでのロックが変わる

SELECT *
FROM TABLE
WHERE EMPNO = ‘000310’;

単純な Where文でも検索対象の対象の列にIndexが張ってあるかないかで
ロック対象が全く異なる。

インデックスがあればオプティマイザはインデックスキャンを選び行ロック(row-level locking == IS)を行う。
インデックスがなければ表全体を検索しなければならず、このときは表ロック(table level lock == S)がかかる。
参考:デッドロックの公式見解

菱田直哉
普通の検索だと、行ロックか表ロックのどちらかがかかっちゃうんだ!

モリー
そう。だからただ検索するためには、「with ur」は有効だね。

モリー
でも、他のトランザクションがコミット前の更新も見えちゃうよ?いいの?
菱田直哉
どういうこと?
モリー
例えば、わたしが間違ったデータを追加して、ロールバックする予定なんだけど、そっちで検索したら見えちゃうってこと。
菱田直哉
それは困るね。間違ったデータは見たくないな。ちゃんとデータベースにコミットされているものだけ見たい。
モリー
それならこうだね。

結果表が読み取り専用であることを明示するには、「SELECT … FOR READ ONLY(またはFETCH ONLY)」を使用します。

菱田直哉
じゃあ「with ur」って何者?

DB2では、UR(Uncommitted Read:非コミット読み取り)、CS(Cursor Stability:カーソル固定)、RS(Read Stability:読み取り固定)、RR(Repeatable Read:反復可能読み取り)がサポートされています。例えば「SELECT * FROM STAFF WITH UR」とすると、非コミット読み取り(最小限のロック)を使用してSELECTが実行されます。
DB2チューニング・ベストプラクティス

菱田直哉
ロックをかけないって目的と、最小限ロックでコミット前の状態も取得できるものは違うんだね。

結論:DB2 テーブルをロックせずにSELECTする方法
select * from TABLE_NAME for read only;

菱田直哉
次からはread onlyを使おっと。