なるので、これらの行を削除することができなくなります。 f00 テープルで参照 していない 3 の値を持つ行は削除することができます。 SELECT a FROM f00 b a 1 1 2 2 3 2 1 ・←子レコードがあるのでエラー DELETE FROM bar WHERE a 3 ・←参照されていないので成功する DELETE FROM bar WHERE a このように、外部キーを設定すると、テープル間にまたがるようなデータの 整合性チェックを行うことが可能になります。 Appendix cna—l テクニック テーブルの列にデフォルト値を与えるには ? システムによる値の自動挿入 テープルの列には、 INSERT によって列情報が与えられなかった場合に、シ ステムが自動的に値を入れるデフォルト値を設定することが可能です。 デフォルト値を持たせるには、 CREATE TABLE 時に列定義に「 DEFAULT default-value 」を加えてテープルを作成します。以下の例では、数値型である 列 b に対してデフォルト値 1 を与えています。 CREATE TABLE f00 ( a 土 n し not null ′ b 土 n し null DEFAULT 1 デフォルト値は、 INSERT で値が明確に指定されなかったときに採用されま す。以下の例で、最初の INSERT では a 、 b 列共に値が与えられていますので、 デフォルト値は採用されません。 2 つめの INSERT は列 a の値しか与えていませ んので、 b 列にはデフォルトの値が入ります。 工 NSERT INTO f00 VALUES ( 1 , 99 ) INSERT INTO f00 (a) VALUES ( 2 ) SELECT * FROM f00 604 .
1 2 3 4 5 6 プロシージャ内で使用できる命令 図表 5-1 Oracle の例外一覧 コレクションが NULL COLLECTION_IS_NULL カーソルを再オープン CURSOR_ALREADY_OPEN 重複した値 DUP VAL ON_INDEX 不正なカーソル INVA 凵 D CURSOR 数値が不正 INVA 凵 D NUMBER ログインに失敗 LOGIN DENIED データなし NO DATA FOUND ログインしていない NOT LOGGED_ON 行タイプの不一致 ROWTYPE MISMATCH 不正な ROWID SYS INVA 凵 D 日 0W2 行が多過ぎる T00 MANY ROWS 代入時の値が不正 VALUE ERROR 0 割りエラー ZERO DIVIDE 複数の例外を捕捉するには WHEN 、 THEN を複数記述します。 INSERT 時に起 こり得る例外のうち、 INVALID—NUMBER 、 DUP—VAL—ON—INDEX の両方を捕 捉するには次のように行います。また、例外に OTHERS を指定すると、 すべて の例外を捕捉することが可能になります。 複数の例外処理を行います。 CREATE PROCEDURE p_fOO (a IN VARCHAR2 , b 工 N NUMBER) 工 S BEG 工 N 工 NSERT INTO f 〇 0 VALUES(a ′ b) : EXCEPT 工 ON WHEN 工 NVAL 工 D_NUMBER THEN DBMS OUTPUT . PUT_L 工 NE い invalid number つ一 WHEN DUP_VAL_ON_ 工 NDEX THEN DBMS_OUTPUT. PUT_LINE( 'duplicate value on index' ) ー WHEN OTHERS THEN DBMS OUTPUT . PUT_L 工 NE('Other exception raised') : 発生する理由 一例外 5.8 例外処理 Oracle END ー 523
1 2 3 4 5 S L と は S Q の 礎 概 ア 構 図表 1 -39 MySQL の文字列型 CHAR [ ( n ) ] [ BINARY ] VARCHAR ( n ) [ BINARY ] TINYTEXT TEXT MEDIUMTEXT LONGTEXT 図表 1 -40 MySQL のバイナリデータ型 TINYBLOB BLOB MEDIUMBLOB LONGBLOB 図表 1 -41 MySQL の列挙型 ENUM ( 'valuel ・ [ , SET('valueI ・ [ , 型に格納できるデータ 固定長文字列。長さは、 n による 可変長文字列。最大長は、 n による 255 バイトまでの可変長文字列 65 , 535 バイトまでの可変長文字列 1 , 677 , 215 バイトまでの可変長文字列 4 , 294 , 967 , 295 バイトまでの可変長文字列 4 , 294 , 967 , 295 バイトまでのバイナリデータ 1 , 677 , 215 バイトまでのバイナリデータ 65 , 535 バイトまでのバイナリデータ 255 バイトまでのバイナリデータ 型に格納できるデータ 型に格納できるデータ 括弧内に指定された任意の文字列 括弧内に指定された任意の文字列の組み合わせ 36
4 5 6 コ マ ン ド ロ卩 Åccess 物準 1 REPLACE 2 ySQ テーブルの既存データ行を更新または新規に追加する REPLACE [INTO 】阨尻 e - れのれ e [()o 襯れ一 7 e し co れ一れ佖襯 e VALUES(value い襯・・・ l) REPLACE [INTO] 阨 e ーれのれ・ e SET co れ一れのれ e = む佖 e [,CO 襯れ一れ佖襯 e = む襯 e … ] REPLACE [INTOI 阨わ厄ーれ佖襯 e [()o 襯れ一れのれ e [,co 襯ーれ佖 e select s 佖一夜れ夜 バラメタ ・テーブル名 阨尻 e れ佖肥・ 列名 COI れ ? ルれれ佖 ? れ e ・ データの値 ・ SELECT 命令 select s 阨このれ夜・・ MySQL では、 Oracle の MERGE と同様な処理を「 REPLACE 」で行うことが可 能です。 REPLACE の利用は、テープルにプライマリキー、ユニークキーが付け られていることが前提となります。 REPLACE に指定されたデータ行が、既存行である場合、各列の値を更新 (UPDATE) します。新規行である場合、行を追加 (INSERT) します。既存行 であるかどうかはキーとなっている列と指定されたデータの値を持つ行が存在す るか、しないかによります。 文法的には、データの指定方法が、 INSERT と同じ方法、 UPDATE と同じ方 法、 SELECT ステートメントによる方法の 3 つがありますが、どれも同じように 機能します。 SE 日 T 形式の日 EPLACE 命令で UPSE 日 T を行います。 RE PLAC E 工 NTO f 00 ( a ′ b ′ c ) VALUE S ( 3 ■ YYY 4 ØØ ) データ操作命令 C)>—J 使用例 UPDATE 形式の REPLACE 命令で UPSERT を行います。 REPLACE 工 NTO f00 SET a=3,b= 'XXX"C=300 ・・ P87 参照 MERGE ・・ 89
1 2 3 4 カレントレコードが先頭または終端を超えていないかを判断するために 5 「 BOF 」、「 EOF 」プロバティを利用することが可能です④ 6 カレントレコードの列の値を参照するには、 OraDynaset オプジェクトの 「 Fields 」コレクションを参照します。 Fields の引数に参照したい列の名前を指定 ロ すると、列に対応した OraFieId オプジェクトが返されます⑤ 0 作成した OraDynaset 、 OraDatabase 、 OraSession オプジェクトは、必要がな ン くなった時点で Close メソッドによって終了を宣言しなければなりません⑩ イ 0040 の例 (Visal Basic) ン タ Sub Main( ) 工 Dim OSession As OraSession Dim ODatabase As OraDatabase ス Dim ODynaset As OraDynaset Dim name AS String Dim age As 工 nteger Dim telephone As String Set OSession CreateObject ( "OracIe 工 nProcServer . XOraSession") ・ Set ODatabase OSession . OpenDatabase("Db", "scott/tiger",Ø&) Set ODynaset ODatabase . CreateDynaset ( "SELECT * FROM Whi1e ODynaset . EOF く > True ・・ name = ODynaset . Fie1ds ( "name" ) . Va1ue age = ODynaset . Fie1ds("age" ) . Value ・・ telephone = ODynaset . Fields ( "telephone" ) . VaIue ODynaset . MoveNext ・ WEnd ODatabase . BeginTrans ・・ ODatabase . ExecuteSQL ( ′ 3 3 ■Ø 3 ー 5 5 5 ー xxxx ー ”工 NSERT INTO f 〇 0 VALUES ( ODatabase . CommitTrans ・・ ODynaset . C10se ODat aba s e . C 1 〇 s e ・・ End Sub 0 0 0040 (OracIe Objects fO 「 OLE) ①② 3 ④⑤⑥②⑧⑨⑩ 551 .
複数行を 1 度に SERT するには ? VALUES( 1 , 2 ) , ( 3 , 4 ) いくつかの行を追加する場合、次のように INSERT 命令を追加する行数分だ け発行する必要があります。 工 NSERT 工 NTO f00 VALUES ( 1 を 2 ) 工 NSERT 工 NTO f00 VALUES ( 3 ′ 4 ) DB2 、 PostgreSQL 、 MySQL では、このような INSERT 命令を 1 つにまとめ ることができます。つまり、 1 回の INSERT 命令で複数の行を追加することがで きます。前の 2 つの INSERT 命令は、次のように 1 回の INSERT 命令で実行する ことができます。 工 NSERT 工 NTO f00 VALUES(1,2), ( 3 ′ 4 ) Oracle では、より高度な INSERT 命令を記述することができます。複数行を 追加するには次のようにします。 工 NSERT ALL 工 NTO f00 VALUES ( 1 ′ 2 ) 工 NTO f00 VALUES ( 3 ′ 4 ) SELECT * FROM DUAL INSERT に続けて ALL と記述します。 INTO f00 VALUES(1,2) と INTO f00 VALUES ( 3 , 4 ) が実際の行の追加指示になります。 INSERT ALL は SELECT 命令を 必要とします。 VALUES により値を指定する場合でも、 SELECT が必要になります。 INSERT ALL では、 INTO 以下にテープルを指定することができるので、同 ーのテープルに行を追加するのではなく、 1 回の INSERT 命令により、別のテー プルに行を追加することも可能です。以下の例では、 f00 テープルに ( 1 , 2 ) の行を、 bar テープルに ( 3 , 4 ) の行を追加します。 工 NSERT ALL 工 NTO f00 VALUES ( 1 ー 2 ) 工 NTO bar VALUES ( 3 ′ 4 ) SELECT * FROM DUAL さらに Oracle では、条件式を使ったより高度な INSERT 命令を記述すること ができます。これについては、次の項で解説します。 ■ Appendix DB2 PostgreSQL MySQL CDO—J テクニック Oracle Oracle 586
1 2 3 4 5 6 コマンド命令 Oracle では、より高度な INSERT 命令を記述することができます。複数行を追 加するには、次のように「 INSERT ALL 」を利用します。 2 行を 1 回の INSE 日 T 命令で追加します。 工 NSERT ALL 工 NTO f 〇 0 VALUES ( 1 ′ 2 ) 工 NTO f 〇 0 VALUES ( 3 ′ 4 ) SELECT * FROM DUAL INSERT に続けて ALL と記述します。「 INTO f00 VALUES(1,2) 」と「 INTO f00 VALUES(3,4) 」が実際の行の追加指示になります。 INSERT ALL は SELECT 命令を必要とします。 VALUES により値を指定する場合でも、 SELECT が必要 になります。 INSERT ALL では、 INTO 以下にテープルを指定することができるので、同一 のテープルに行を追加するのではなく、 1 回の INSERT 命令により、別のテープ ルに行を追加することも可能です。 さらに、 Oracle では、「 WHEN 」及び「 THEN 」を利用して、条件により追加す タ るテープルを振り分ける、といった処理を行うことができます。 WHEN 、 THEN の使い方は、 CASE と似ています。 KÄINSERT ALL の WHEN THEN によ引 NSE 日 T するテープル振り分け ます。 工 NSERT ALL 1 ØØØ 0 THEN WHEN a く barl 工 NTO Oracle ロ卩 Oracle ELSE bar2 工 NTO b FROM fo 〇 SELECT a ′ 79
SQL POStg 「 0 ySQ cces 標準 1 D82 acl INSERT 2 3 4 5 6 コマンド命令 テーカレにデータ行を追加する INSERT ー INTO 】阨わーのれ e ー ( co 襯れい co 襯れ ... ] ) 】 { VALUES ( む佖 e [ , む襯 e … ] ) な e 厄ー s 阨川夜 } INSERT ALL INTO 阨况 e ーれのれ e VALUES ( の佖 e [ , む襯 e ー INTO 阨わ厄ーれのれ e VALUES ( む襯 e にの佖 e …】 ) .. ] se 厄ー $ このれ夜 Oracle バ同区三ダ ・行を追加するテーブル名 阨わーれ佖襯 e ・ ・挿入する列の値 ・列名 COI ~ れ・ ・ SELECT 命令 select s 阨 m. の・・ タ 日 NSERT 」命令を使用すると、テープルに行を追加することができます。 作 SQL Server 、 MySQL では INTO を省略できますが、 Oracle 、 DB2 、 PostgreSQL 、 Access では必ず記述します。値は「 VALUES 」に続く括弧の中に記述します。 の時、追加するテープルの定義通りに順番に記述していきます。文字列型の値を 記述する場合には、 'String Data' のようにシングルクオーテーションで囲って文 字列値であることを示します。 NULL 値を追加する場合は NULL と記述しますが、 NOTNULL 指定の列に対して行うとエラーとなります。 foo テーブルに行を追加します。 工 NSERT 工 NTO f00 VALUES ( 1 ′ 2 ,'ABC つ ロ卩 ・列を限定した SERT 列を指定するとその列のみの値だけを追加することができます。指定しなかっ た列の値はデフォルトが定義されていればデフォルト値が、定義されていなけれ ば NULL 値となります。また、 NOT NULL 指定されている列は、必ず値を指定 しなければなりません。列指定の順番は任意ですが、 VALUES に続く値と対応が 取れている必要があります。 77 .
この問題を解決するには、ビューに対して ROWNUM を使用するか、 FROM に サプクエリーを記述して回避します。 PostgreSQL 、 MySQL では、「凵 M 灯句」が利用できます。 LIMIT 句による行 制限は、ソート後に行われますので、期待する結果を得ることができます。上 位 10 件の結果だけを得るには次のように行います。 SELECT * FROM f00 ORDER BY a L 工 MIT IO INSERT VALUES に式を与えると ? DEFAULT 値・シーケンス値 PostgreSQL MySQL INSERT の VALUES には定数値だけでなく、式を記述することが許されています。 Access 以外のデータベースではデフォルト値を INSERT する時には、明示的 に「 DEFAULT 」を指定することが可能です。ただし、テープルにデフォルト値 が設定されている必要があります。 Access では DEFAULT という記述は許され ません。テープルに定義されている列のうち、 INSERT 時の列指定にないもの は NULL 値で追加されますが、列にデフォルト値が指定されている場合にはそ の値で行が追加されます。以下の例では f 。。テープルの最初の列が a であるとす ると、 2 つの INSERT の結果は同じになります。 INSERT 工 NTO f00 VALUES ( 1 ′ DEFAULT, DEFAULT) INSERT INTO f00 (a) VALUES ( 1 ) Oracle 、 DB2 、 PostgreSQL では、シーケンスの次の値で INSERT することが 可能です。シーケンスは順番を管理することができるオプジェクトです。 SQL Server にはシーケンスはありません。シーケンスの「 NEXTVAL 」疑似列を参 照すると、シーケンス内部で保存されている値が加算されて返されます。 工 NSERT 工 NTO f00 ( i ) VALUES ( seq . NEXTVAL ) Oracle 0 ク ツ ク 585.
1 2 3 4 DECLARE res 工 NTEGER; DECLARE val 工 NTEGER DEFAULT 1 : 6 res FROM bar WHERE a SELECT a INTO NULL THEN 工 F r e s 工 S NOT ロ シ result VALUES ('Found') : 工 NSERT 工 NTO シ ELSE ヤ result VALUES い N 〇し Found') : 内 INSERT 工 NTO で END 工 F : 用 END き る いくつもの条件により分岐させること DB2 、 MySQL では、 ELSEIF を使って、 ができます。 ELSE と IF の間にスペースを置きません。 ELSEIF のように続けて 記述します。 引数が O の場合 ' ze 「 0 ' を、 1 のとき・ one ・、それ以外の場合、 'not ze 「 0 and one ' と処理するプロシージャを定義します。 CREATE PROCEDURE test_ifthen—elseif ()N a 工 NTEGER) LANGUAGE SQL BEG 工 N Ø THEN 工 F a INTO result VALUES ( 工 NSERT 1 THEN ELSEIF a 工 NTO result VALUES ( INSERT ELSE ー〇亡 zero and one ー ) ー 工 NTO result VALUES ( 工 NSERT END 工 F ー END 5 val; ロ卩 DB2 MySQL 条件を判断するには ・ PostgreSQL 「旧」の次に評価したい条件式を記述します。条件式が真である場合、「 THEN 」 以下の命令が実行されます。「 ELSEIF 」が記述されている場合は、それらの条件 式を順番に評価していきます。すべての条件式が偽である場合、「 ELSE 」以下の 命令が実行されます。 ELSEIF や ELSE の処理が必要ないときは、 ELSEIF 、及び ELSE を省略することが可能です。最後に「 ENDIF 」を記述します。 IF 命令は ENDIF までが 1 つのステートメントになりますので、 ENDIF の最後 491