DB2でストアドプロシージャを作ってコールする
[]

2010.09.12

このエントリーをはてなブックマークに追加
はてなブックマーク - DB2でストアドプロシージャを作ってコールする

実行環境は以下の通り

  • OS X 10.6.2
  • DB2 Express-C

DB2では以下の2種類のストアドプロシージャがある:

  • SQLプロシージャ:SQLで定義されたプロシージャ
  • 外部プロシージャ:SQL以外(C言語とか)で定義されたプロシージャ

とりあえず、今回は簡単に作れそうな SQLプロシージャを作る。 内容としては引数無しで、データをインサートするだけのストアドプロシージャを作ってコールしてみる。

定義

-- test_proc1.sql
CREATE PROCEDURE insert_sale()
LANGUAGE SQL MODIFIES SQL DATA
INSERT INTO sales VALUES('2010-01-01', 'yokada', 'japan', 1)
@

作成

$ db2 -td@ -f test_proc1.sql

DB20000I  The SQL command completed successfully.

呼び出し

$ db2 'call insert_sale()'

  Return Status = 0

実行確認

$ db2 "select * from sales where sales_person = 'yokada'"

SALES_DATE SALES_PERSON    REGION          SALES      
---------- --------------- --------------- -----------
2010-01-01 yokada          japan                     1

DB2コマンドでコマンドラインからSQLを実行する
[]

2010.09.12

このエントリーをはてなブックマークに追加
はてなブックマーク - DB2コマンドでコマンドラインからSQLを実行する

$ source sqllib/db2profile         #<== すでに設定ファイルを読み込んでいるなら不要
$ db2start        #<== すでにdb2を起動しているなら不要
$ db2 connect to sample           #<== すでにsampleデータベースに接続しているなら不要
$ db2 "select * from sales"

SALES_DATE SALES_PERSON    REGION          SALES      
---------- --------------- --------------- -----------
2005-12-31 LUCCHESSI       Ontario-South             1
2005-12-31 LEE             Ontario-South             3
2005-12-31 LEE             Quebec                    1
2005-12-31 LEE             Manitoba                  2
2005-12-31 GOUNOT          Quebec                    1
2006-03-29 LUCCHESSI       Ontario-South             3
2006-03-29 LUCCHESSI       Quebec                    1
2006-03-29 LEE             Ontario-South             2

... 省略

  42 record(s) selected.

参考

DB2でSQLのexplain情報を取得する
[]

2010.09.12

このエントリーをはてなブックマークに追加
はてなブックマーク - DB2でSQLのexplain情報を取得する

  • OS X 10.6.2
  • DB2 express-c 9.5

explain表の作成

$ db2 -tvf sqllib/misc/EXPLAIN.DDL

Explainの対象となるSQLの作成と実行

作成

--
-- test_explain.sql
--
EXPLAIN ALL WITH snapshot FOR
SELECT * FROM sales
@

実行

$ db2 -td@ -f test_explain.sql

Explain情報の取得

$ db2exfmt -d sample -s % -e yokada -n % -w -1 -# 0 -o test_explain_result.txt;


> 続きを読む

DB2 で VIEW を作成する
[]

2010.09.12

このエントリーをはてなブックマークに追加
はてなブックマーク - DB2 で VIEW を作成する

  • OS X 10.6.2
  • DB2 9.5
--
-- test_create_view.sql
--
CREATE VIEW sales_view AS
  SELECT
    ROWNUMBER() OVER(ORDER BY sales_date) AS rownum -- 行番号を追加する
    , sales_date
    , sales_person
    , region
    , sales
  FROM sales
@

SELECT * FROM sales_view
@

SQLを実行する

$ db2 -td@ -f test_create_view.sql

$ db2 -td@ -f test_db2/sales01.sql
DB20000I  The SQL command completed successfully. #<== CRETE VIEW が成功した

ROWNUM               SALES_DATE SALES_PERSON    REGION          SALES      
-------------------- ---------- --------------- --------------- -----------
                   1 1996-03-29 LEE             Ontario-North             2
                   2 2005-12-31 LUCCHESSI       Ontario-South             1
                   3 2005-12-31 LEE             Ontario-South             3
                   4 2005-12-31 LEE             Quebec                    1
                   5 2005-12-31 LEE             Manitoba                  2
                   6 2005-12-31 GOUNOT          Quebec                    1
                   7 2006-03-29 LUCCHESSI       Ontario-South             3
                   8 2006-03-29 LUCCHESSI       Quebec                    1
                   9 2006-03-29 LEE             Ontario-South             2
                  10 2006-03-29 LEE             Quebec                    3
                  11 2006-03-29 LEE             Manitoba                  5
                  12 2006-03-29 GOUNOT          Ontario-South             3

DB2 で制約を定義する
[]

2010.09.12

このエントリーをはてなブックマークに追加
はてなブックマーク - DB2 で制約を定義する

環境

  • OS X 10.6.2
  • DB2 9.5
$ db2level
DB21085I  Instance "yokada" uses "64" bits and DB2 code release "SQL09052" with
level identifier "03030107".
Informational tokens are "DB2 v9.5.0.2", "s081205", "DARWIN64", and Fix Pack
"2".
Product is installed at "/Users/yokada/sqllib".

テーブルを定義する

ちなみに、「SQLパズル」のパズル1を参考にしています。

CREATE TABLE FiscalYearTable1(
  fiscal_year INTEGER NOT NULL
  , start_date DATE NOT NULL UNIQUE
  , end_date DATE NOT NULL UNIQUE
  -- start_date は end_date と等しいか小さいはずだ.
  , CONSTRAINT start_date_is_less_or_equal_than_end_date
    CHECK ( start_date <= end_date )
  -- start_date の年は fiscal_yearから1引いた値と等しいはずだ.
  -- start_date の月は 10 であるはずだ.
  -- start_date の日は 01 であるはずだ.
  , CONSTRAINT valid_start_date
    CHECK ( ( YEAR ( start_date ) = fiscal_year - 1 )
      AND ( MONTH ( start_date ) = 10 )
      AND ( DAYS ( start_date ) = 01 ) )
  -- end_date の年は fiscal_year と等しいはずだ.
  -- end_date の月は 09 であるはずだ.
  -- end_date の日は 30 であるはずだ.
  , CONSTRAINT valid_end_date
    CHECK ( ( YEAR( end_date ) = fiscal_year )
      AND ( MONTH( end_date ) = 09 )
      AND ( DAYS( end_date ) = 30 ) )
  , PRIMARY KEY(fiscal_year)
)
@

-- わざと制約(start_date_is_less_or_equal_than_end_date)違反な行をインサートしてみる。
INSERT INTO FiscalYearTable1 VALUES(2010, '2011-10-01', '2011-09-30')
@

SQLを実行する

$ db2 -td@ -f sql_puzzle/01_db2/create_table.sql
DB21034E  The command was processed as an SQL statement because it was not a
valid Command Line Processor command.  During SQL processing it returned:
SQL0545N  The requested operation is not allowed because a row does not
satisfy the check constraint
"YOKADA.FISCALYEARTABLE1.START_DATE_IS_EARLYER_OR_EQUAL_THAN_END_DATE".  
SQLSTATE=23513

START_DATE_IS_EARLYER_OR_EQUAL_THAN_END_DATE という列制約違反が発生したので制約が効いていることが確認できた。

References

  • DB2 SQL Cookbook:このサイトは英語ですがかなりおすすめ。豊富なサンプルと多くのキーワードを網羅しています。

DB2 SQL サンプル
[]

2010.05.18

このエントリーをはてなブックマークに追加
はてなブックマーク - DB2 SQL サンプル

env

SQL メモ
[]

2010.03.30

このエントリーをはてなブックマークに追加
はてなブックマーク - SQL メモ

前提

  • DB2 v9.1

各句の(基本的な)実行順序

  1. (最も内側のFROM句のサブクエリ)
  2. FROM 句
  3. JOIN ON 句
  4. WHERE 句
  5. GROUP BY 句 および 集計関数
  6. HAVING 句
  7. SELECT 句
  8. ORDER BY
  9. FETCH FIRST

なので、SQLを組み立てるときはFROM句から考えるとよいらしい。


> 続きを読む

DB2でcase式の検索条件にEXISTSを使うとエラーになる
[]

2010.03.29

このエントリーをはてなブックマークに追加
はてなブックマーク - DB2でcase式の検索条件にEXISTSを使うとエラーになる

環境

  • DB2 v9.1

試したSQL

SELECT T1.C1,
  CASE WHEN EXISTS
      (SELECT * FROM TBL2 WHERE C2 = '0001' ) THEN 1
  ELSE 0 END
FROM TBL1 AS T1
-- 結果
-- トークン EXISTS は正しくない。有効なトークンは<IDENTIFIER> <INTEGER>...

マニュアルを見てみた。

以下は183ページより引用。

search-condition
行または表データのグループについて、真、偽、または不明の条件を指定します。
検索条件には、EXISTS または IN 述部に副照会を組み込むことはできません。

マジですか。

集計関数で対応

SELECT T1.C1,
  CASE WHEN
      (SELECT COUNT(*) FROM TBL2 WHERE C2 = '0001' ) > 0 THEN 1
  ELSE 0 END
FROM TBL1 AS T1