記事一覧へ戻る

掲載元
Oracle Magazine
2012年11/12月

テクノロジー:SQLの基礎

  

状況に合った型の選択

著者:Melanie Caffrey

 

リレーショナル・データベースとSQLの基本に関するシリーズ記事のパート8

このシリーズ記事のパート7 "FLOOR、CEILINGなどの数値関数やその他の機能的なケースについて"(Oracle Magazine、2012年9/10月)では、よく使用されるSQL数値関数を紹介し、問合せを利用して、数値で構成される結果セット・データの表示を変更する方法について説明しました。また、SQL置換関数を紹介し、よりわかりやすい結果を得るために、SQL置換関数を利用して結果セット・データを操作する方法についても説明しました。同様に、SQLの日付関数データ型変換関数を使用すれば、データベースに格納された形式とは異なる形式で表示するようにデータを操作できます。この記事では、比較的よく使用されるSQL日付関数のほか、便利なデータ型変換関数をいくつか紹介します。

このシリーズ記事の例を試すには、Oracle Databaseインスタンスにアクセスする必要があります。必要に応じて、お使いのオペレーティング・システムに対応したOracle Databaseエディションをダウンロードし、インストールしてください。筆者がインストールをお勧めするエディションは、Oracle Database, Express Edition 11g Release 2です。

このOracle Databaseソフトウェアをインストールする場合は、データベースの作成と構成が可能なインストール・オプションを選択してください。サンプルのユーザー・アカウントと関連する新しいスキーマを含む新しいデータベースが作成されます(SQL_101は、このシリーズ記事の例で使用するユーザー・アカウントです。また、データベースの表やその他のオブジェクトが作成されるスキーマでもあります)。インストール・プロセスの実行中にスキーマのパスワードを指定するように求められたら、SYSおよびSYSTEMのパスワードを入力して確認し、そのパスワードを覚えておいてください。

最後に、このデータベース・ソフトウェアをゼロからインストールした場合でも、既存のOracle Databaseインスタンスにアクセスする場合でも、SQLスクリプトをダウンロードして解凍し、実行して、この記事の例で必要となるSQL_101スキーマ用の表を作成します(このスクリプトをテキスト・エディタで開き、実行方法の説明を参照してください)。一部の例ではDUAL表も使用します。すでに説明したとおり、DUALは、SQL_101スキーマではなくSYSユーザーが所有するOracleシステム表です。DUAL表自体には意味のあるデータは含まれませんが、リテラルに対して動作する関数を試す手段として問合せの対象とすれば便利です。

最適な日付書式

DATEデータ型は、Oracle Database内では日付と時刻(世紀、年、月、日、時、分、秒)の両方の情報で構成される内部形式として格納されます。すべてのOracle Databaseインスタンスには、日付の入出力のためのデフォルトの日付書式モデル(別名:マスク)があります。
この日付書式モデルはNLS_DATE_FORMATという初期化パラメータによって設定します(初期化パラメータは、Oracle Databaseインスタンスのデフォルト設定を指定するものです。適切な権限を持つユーザーが、データベースごと、インスタンスごと、またはセッションごとに、初期化パラメータの一部を変更できます)。ある表のDATEデータ型の列に保管されたデータを初めて問い合わせると、Oracle Databaseでは、デフォルト設定に応じてDD-MON-YYYYまたはDD-MON-RRの書式マスクによってそのデータが表示されます。

RRという書式マスクは2桁の年を表すもので、2000年問題などの世紀末の問題に対処するために導入されました。RRを使用した2桁の年は、現在の年と問合せで指定した2桁の年に応じて、前世紀、今世紀、次世紀のいずれかの年を表します。表1に、現在の年と2桁の年の範囲の組合せ、その結果として想定される世紀の関係を示します。

現在の年の末尾2桁 問合せで指定した2桁の年 想定される世紀
00~49 00~49 今世紀
00~49 50~99 前世紀
50~99 00~49 次世紀
50~99 50~99 今世紀
表1:現在の年、指定した2桁の年、結果として想定される世紀の関係

たとえば、現在の年(2012年)の末尾2桁は12で、00~49の範囲内にあります。2012年のうちに実行したSQL問合せで、RRの年の値として15を指定した場合は、今世紀(21世紀)の末尾15の年(2015年)と見なされます(15が0~49の範囲内にあるため)。2012年に実行した問合せで、RRの年の値として98を指定した場合は、前世紀(20世紀)の末尾98の年(1998年)と見なされます(98が50~99の範囲内にあるため)。

リスト1の問合せでは、この記事のサンプル・スキーマ内にあるEMPLOYEE表を利用します。この問合せによって、雇用日が新しい順でソートされた従業員情報が表示されます。ご覧のとおり、雇用日のデータはDD-MON-RRという書式で表示されます。たとえば、Roger Friedliは16-MAY-07に雇用されています。このデータの表示方法を変更するには、TO_CHAR変換関数を任意の書式モデルとともに使用します(TO_CHARについては前回の記事で、数値をテキスト文字列に変換するために使用できることを簡単に紹介しました)。

コード・リスト1:Oracle Databaseのデフォルトの日付書式による日付データの表示 

SQL> set feedback on
SQL> select first_name, last_name, hire_date
  2    from employee
  3  order by hire_date desc, last_name, first_name;

FIRST_NAME       LAST_NAME        HIRE_DATE
———————————————  ———————————————  —————————————
Theresa          Wong             27-FEB-10
Thomas           Jeffrey          27-FEB-10
mark             leblanc          06-MAR-09
michael          peterson         03-NOV-08
Roger            Friedli          16-MAY-07
Betsy            James            16-MAY-07
Matthew          Michaels         16-MAY-07
Donald           Newton           24-SEP-06
Frances          Newton           14-SEP-05
Emily            Eckhardt         07-JUL-04

10 rows selected. 

 

リスト2の問合せで、リスト1での日付データの表示方法を変更します。DATEデータ型のデータを特定の日付書式モデルに変換するためのTO_CHARは、必須パラメータ1つとオプションのパラメータ1つを指定します。必須パラメータは、列、式、またはリテラルのDATEデータ型のデータです。オプションのパラメータは、表示される日付の書式マスクをテキストで表現したものです。リスト2では、DD-MON-RRというデフォルトの書式マスクを、YYYY-MM-DDと表示するように変更しています。

コード・リスト2:TO_CHARを書式マスク付きで使用して、異なる書式で日付データを表示する例 

SQL> select first_name, last_name, TO_CHAR(hire_date, 'YYYY-MM-DD') hire_date
  2    from employee
  3  order by hire_date desc, last_name, first_name;

FIRST_NAME       LAST_NAME        HIRE_DATE
———————————————  ———————————————  —————————————
Thomas           Jeffrey          2010-02-27
Theresa          Wong             2010-02-27
mark             leblanc          2009-03-06
michael          peterson         2008-11-03
Roger            Friedli          2007-05-16
Betsy            James            2007-05-16
Matthew          Michaels         2007-05-16
Donald           Newton           2006-09-24
Frances          Newton           2005-09-14
Emily            Eckhardt         2004-07-07

10 rows selected.

 

リスト3の例では、TO_CHARの第2パラメータがオプションであることがわかります。このパラメータを指定しない場合、返される日付データの書式マスクは単にデフォルトの書式マスクです。また、返される日付のデータ型がVARCHAR2である点にも注意が必要です。リスト3の出力はHIRE_DATEの降順でソートされていますが、日付ではなく文字の降順です。TO_CHAR変換関数を適用するとデータが文字列として返されるため、それに応じた計画とソートが必要です。

コード・リスト3:オプションのパラメータを指定しない場合にデフォルトの日付書式マスクが使用される例 

SQL> select first_name, last_name, TO_CHAR(hire_date) hire_date_formatted
  2    from employee
  3  order by hire_date_formatted desc, last_name, first_name;

FIRST_NAME       LAST_NAME        HIRE_DATE
———————————————  ———————————————  —————————————
Thomas           Jeffrey          27-FEB-10
Theresa          Wong             27-FEB-10
Donald           Newton           24-SEP-06
Roger            Friedli          16-MAY-07
Betsy            James            16-MAY-07
Matthew          Michaels         16-MAY-07
Frances          Newton           14-SEP-05
Emily            Eckhardt         07-JUL-04
mark             leblanc          06-MAR-09
michael          peterson         03-NOV-08

10 rows selected.

 

文字列付きの日付

日付を文字列に変換できるのと同様に、文字列リテラルを日付に変換できます。その結果の式は、他のDATEデータ型列のデータや他の日付式と比較できます。この変換は、テキスト文字列にTO_DATE変換関数を適用することで実行します(リスト4を参照)。リスト4の問合せでは、HIRE_DATEの値が01-JAN-2008という日付値よりも大きい従業員がすべて返されます。また、リスト4より、TO_DATE変換関数はSELECT構文のリスト内でもWHERE句内でも使用できることがわかります。TO_DATE関数は01-JAN-2008という文字列リテラルに適用されます。この際に、指定したリテラルを日付としてデータベースで解釈できるようにするための書式マスクも記述しています。

コード・リスト4:WHERE句でのTO_DATE変換関数の使用例 

SQL> select first_name, last_name, TO_CHAR(hire_date, 'DD-MON-YYYY') hire_date
  2    from employee
  3   where hire_date > TO_DATE('01-JAN-2008', 'DD-MON-YYYY')
  4  order by hire_date desc, last_name, first_name;

FIRST_NAME       LAST_NAME        HIRE_DATE
———————————————  ———————————————  —————————————
Thomas           Jeffrey          27-FEB-2010
Theresa          Wong             27-FEB-2010
mark             leblanc          06-MAR-2009
michael          peterson         03-NOV-2008

4 rows selected.

 

TO_DATE関数に書式マスクを指定する場合には、指定する文字列リテラル内で使用されるマスクと同じものを選択する必要があります。この2つが異なると、リスト5のようなエラー・メッセージが表示されます。テキスト・リテラルを変換する際には、TO_DATE変換関数を使用して適切な書式マスクを明示的に指定することをお勧めします。このようにすれば、データベース、インスタンス、またはセッションのデフォルトの日付設定が何であっても、記述した文が独立して解釈されます。

コード・リスト5:指定した文字列リテラルに書式マスクが一致しない場合のエラー 

SQL> select first_name, last_name, TO_CHAR(hire_date, 'DD-MON-YYYY') hire_date
  2    from employee
  3   where hire_date > TO_DATE('01-JAN-2008', 'MM/DD/RR')
  4  order by hire_date desc, last_name, first_name;
 where hire_date > TO_DATE('01-JAN-2008', 'MM/DD/RR')
                           *
ERROR at line 3:
ORA-01858: a non-numeric character was found where a numeric was expected

 

Oracle Databaseでは、可能な場合に日付の暗黙的変換が実行されます。この変換が実行されるのは、リテラルがすでにデフォルトの日付書式で指定されている場合(のみ)です。ただし、暗黙的変換を実行しないようにすることをお勧めします。暗黙的変換を実行するようなコードは脆弱で、長期的に機能する可能性が低いからです。
リスト6は、Oracle Databaseでのデフォルトの日付書式を利用する問合せです。この問合せは、文字列リテラルに対して日付の暗黙的変換が実行されることを示しています。リスト6の結果とリスト7の結果を比較してみましょう。リスト7でも日付の暗黙的変換を実行しようとしていますが、失敗しています。これは、EMPLOYEE表のHIRE_DATE列の値と比較されるリテラル値の日付書式マスクがデータベースで解釈できないからです。

コード・リスト6:日付の暗黙的変換(非推奨)により結果セットが返される例 

SQL> select first_name, last_name, TO_CHAR(hire_date, 'DD-MON-YYYY') hire_date
  2    from employee
  3   where hire_date > '01-JAN-2008'
  4  order by hire_date desc, last_name, first_name;

FIRST_NAME       LAST_NAME        HIRE_DATE
———————————————  ———————————————  —————————————
Thomas           Jeffrey          27-FEB-2010
Theresa          Wong             27-FEB-2010
mark             leblanc          06-MAR-2009
michael          peterson         03-NOV-2008

4 rows selected.

 

コード・リスト7:日付の暗黙的変換の試行が失敗する例 

SQL> select first_name, last_name, TO_CHAR(hire_date, 'DD-MON-YYYY') hire_date
  2    from employee
  3   where hire_date > '01/01/2008'
  4  order by hire_date desc, last_name, first_name;
 where hire_date > '01/01/2008'
                   *
ERROR at line 3:
ORA-01843: not a valid month

 

デフォルトの日付書式は変更される可能性があるため、予想されるデフォルト書式に依存した問合せにしないことが最善策です。代わりに、日付の文字列リテラルでは常にTO_DATE関数を使用してください。現在のセッションで使用しているデフォルトの日付書式を把握する1つの方法として、リスト8に示す問合せを実行します。SYS_CONTEXT関数はすべてのセッション(すなわち、すべてのユーザー)が使用できる関数であり、現在のセッション属性を確認できます。

コード・リスト8:現在のセッションにおけるデフォルトの日付書式の確認 

SQL> select sys_context ('USERENV', 'NLS_DATE_FORMAT')
  2    from dual;

SYS_CONTEXT('USERENV','NLS_DATE_FORMAT')
————————————————————————————————————————————————
DD-MON-RR

1 row selected.

 

日付データによる時刻の取得

すでに説明したとおり、Oracle DATEデータ型には時刻部分が含まれています。時刻部分については、この記事のこれまでの例のように無視することもできますが、表示や比較の目的で結果に含めることもできます。リスト9に、時刻部分を含む問合せを示します。この問合せでは、EMPLOYEE表内のすべての従業員について、各HIRE_DATEの値に時刻部分が含まれます。ここで、Theresa Wong以外のすべての従業員レコードの時刻値が12:00:00である点に注意してください。DATEデータ型の列に値を挿入するときに時刻を含めない場合、時刻はデフォルト値の午前0時(12:00:00 a.m.または24時間制の00:00:00)に設定されます。24時間制で日付値の表示や比較を行うには、HHではなくHH24という書式マスクを使用します。

コード・リスト9:DATEデータ型の値に関する時刻部分の表示 

SQL> set lines 32000
SQL> select first_name, last_name, TO_CHAR(hire_date, 'DD-MON-YYYY HH:MI:SS') hire_date
  2    from employee
  3  order by hire_date desc, last_name, first_name;

FIRST_NAME       LAST_NAME        HIRE_DATE
———————————————  ———————————————  —————————————
Thomas           Jeffrey          27-FEB-2010 12:00:00
Theresa          Wong             27-FEB-2010 09:02:45
Donald           Newton           24-SEP-2006 12:00:00
Roger            Friedli          16-MAY-2007 12:00:00
Betsy            James            16-MAY-2007 12:00:00
Matthew          Michaels         16-MAY-2007 12:00:00
Frances          Newton           14-SEP-2005 12:00:00
Emily            Eckhardt         07-JUL-2004 12:00:00
mark             leblanc          06-MAR-2009 12:00:00
michael          peterson         03-NOV-2008 12:00:00

10 rows selected.

 

フィルタリング対象の日付値について正確な時刻を知っている場合、あるいは日付値の時刻部分のすべてがすでに午前0時に設定されている場合を除き、WHERE句内で日付値を使用すると予期せぬ結果になることがあります。リスト10の問合せを見てみましょう。これまでのリストの結果より、2人の従業員が2010年2月27日に雇用されたことがわかっていますが、リスト10の結果セットには1人しか返されていません。その理由として、WHERE句のTO_DATE関数で正確な時刻を指定していないため、Oracle Databaseにより時刻が午前0時であると見なされ、指定した日付値で、かつ時刻部分が午前0時であるレコードのみが返されます。

コード・リスト10:TO_DATEを使用したWHERE句で、可能な値のすべてが取得されない例 

SQL> select first_name, last_name, TO_CHAR(hire_date, 'DD-MON-YYYY HH:MI:SS') hire_date
  2    from employee
  3   where hire_date = TO_DATE('27-FEB-2010', 'DD-MON-YYYY')
  4  order by last_name, first_name;

FIRST_NAME       LAST_NAME        HIRE_DATE
———————————————  ———————————————  —————————————
Thomas           Jeffrey          27-FEB-2010 12:00:00

1 row selected.

  

次のステップ


 その他の記事 SQLの基礎、パート1~7

日付とデータ型変換関数の詳細
 数値書式要素
 日時関数

リレーショナル・データベースの
設計と概念に関する詳細の確認
 Oracle Database概要 11gリリース2 (11.2)
 Oracle Database SQL言語リファレンス11g リリース1(11.1)
 Oracle SQL Developerユーザーズ・ガイド リリース3.1

Oracle Database開発の要点
 Oracle® Database2日で開発者ガイド 11gリリース2 (11.2)

 ダウンロード この記事のサンプル・スクリプト

日付の短縮化

ある特定の日付に基づいてフィルタリングしながらも、個々の時刻部分を含めない場合に、いくつかの方法を利用できます。1つの方法は、TRUNC関数を使用することです(この関数については、前回の記事で紹介しました)。

TRUNC関数は、TO_CHAR関数と同様に、数値だけではなく日付値にも機能します。TRUNC関数は、オプションの書式パラメータが渡されていない場合は、日付の時刻部分を切り捨てます。

この機能は、日付を比較する場合に便利です。リスト11に、リスト10の問合せの改良版を示します。見てのとおり、HIRE_DATE列の値の時刻部分を除去することで、27-FEB-2010という日付値との比較が可能になり、時刻にかかわらずHIRE_DATEの値が27-FEB-2010であるすべてのレコードが取得されます。

切り捨てられたHIRE_DATE値は日付のみの値に変わります。この値が、日付のみの書式を持つ27-FEB-2010というリテラル文字列に対してTO_DATE関数を適用した結果返される、対応する日付のみの値と比較されます。

コード・リスト11:DATE値から時刻を切り捨てて、特定の日付と合致するすべてのレコードを返す例 

SQL> select first_name, last_name, TO_CHAR(hire_date, 'DD-MON-YYYY HH:MI:SS') hire_date
  2    from employee
  3   where TRUNC(hire_date) = TO_DATE('27-FEB-2010', 'DD-MON-YYYY')
  4  order by last_name, first_name;

FIRST_NAME       LAST_NAME        HIRE_DATE
———————————————  ———————————————  —————————————
Thomas           Jeffrey          27-FEB-2010 12:00:00
Theresa          Wong             27-FEB-2010 09:02:45

2 rows selected.

 

ただし、WHERE句内にある表の列値に対して関数を適用すればパフォーマンスが低下するおそれがある点に注意してください。索引(このシリーズ記事では取り上げませんが、データ・アクセスの効率化のために使用します)により、特定の状況での問合せパフォーマンスが向上します。しかし、ある表の列に関数を適用すると、その列の索引が使用されなくなる場合があります。また、この関数は、すべての行のその列に対応するすべての値に適用されます。

このどちらの動作も、パフォーマンスの大きな阻害要因になります。そのため、別の方法を使用できます。それは、実際にフィルタリングの対象とする日付(複数可)に含まれない日付範囲を指定することです。リスト12の問合せにより、リスト11の問合せと同じ結果セットが取得されます。リスト11とリスト12の違いは、リスト12の問合せではHIRE_DATE列のデータに関数を適用していないことです。そうではなく、求める日付(複数可)のすぐ外側の範囲を選択して、フィルタリング対象の日付データがこの値の範囲内に含まれるようにします。

コード・リスト12:特定の日付に合致するレコードを返す日付範囲 

SQL> select first_name, last_name, TO_CHAR(hire_date, 'DD-MON-YYYY HH:MI:SS') hire_date
  2    from employee
  3   where hire_date >= TO_DATE('27-FEB-2010', 'DD-MON-YYYY')
  4     and hire_date <  TO_DATE('28-FEB-2010', 'DD-MON-YYYY')
  5  order by last_name, first_name;

FIRST_NAME       LAST_NAME        HIRE_DATE
———————————————  ———————————————  —————————————
Thomas           Jeffrey          27-FEB-2010 12:00:00
Theresa          Wong             27-FEB-2010 09:02:45

2 rows selected.

 

日付を正しく取得するためのシステム

日付計算を実行しなければならないこともよくあります。この際の便利な組込み関数(Oracle Databaseにすでに組み込まれている関数)がSYSDATEです。この関数は、データベースがインストールされたコンピュータのオペレーティング・システムに設定されている現在の日付と時刻を返します。この関数にはパラメータはありません。リスト13に、SYSDATE関数を使用し、現在の日付と時刻を返して表示する例を示します。

コード・リスト13:SYSDATE関数 

SQL> select SYSDATE, TO_CHAR(SYSDATE, 'DD-MON-YYYY HH24:MI:SS') sysdate_with_time
  2    from dual;

SYSDATE   SYSDATE_WITH_TIME
———————   ——————————————————————————————
08-AUG-12 08-AUG-2012 14:25:08

1 row selected.

 

SYSDATEは日付計算において非常に便利です。リスト14の問合せは、本日(例では2012年8月8日)から数えた2012年の残りの日数を示します。この例で、仮にSYSDATE値を切り捨てないとすると、返されるDAYS_TILL_2013値には、SYSDATE値の断片的なデータ(時刻部分に対応するもの)が含まれます。しかし、この例ではSYSDATE値が切り捨てられるため、本日1日分を含めて2013年1月1日から減算され、この年は残り146日であるという結果が出されます。リスト15では、EMPLOYEE表のHIRE_DATE列に対してSYSDATEと日付計算(MONTHS_BETWEENという日付関数)を使用して、各従業員の勤務年数を表示します。

コード・リスト14:日付計算でのSYSDATEの使用例 

SQL> select SYSDATE, (TO_DATE('01-JAN-2013', 'DD-MON-YYYY') - TRUNC(SYSDATE)) 
Days_till_2013
  2    from dual;

SYSDATE     DAYS_TILL_2013
——————————  ——————————————
08-AUG-12   146

1 row selected.

 

コード・リスト15:SYSDATEおよび日付計算とDATEデータとの組合せ 

SQL> select substr(last_name, 1, 10) last_name, substr(first_name, 1, 10) 
first_name, hire_date, ROUND(MONTHS_BETWEEN(TRUNC(SYSDATE), TRUNC(HIRE_
DATE))/12, 2) YEARS_OF_SERVICE
  2    from employee
  3  order by years_of_service desc, last_name, first_name;

LAST_NAME  FIRST_NAME  HIRE_DATE  YEARS_OF_SERVICE
—————————  ——————————— —————————    ——————————————
Eckhardt   Emily       07-JUL-04             8.09
Newton     Frances     14-SEP-05              6.9
Newton     Donald      24-SEP-06             5.88
Friedli    Roger       16-MAY-07             5.23
James      Betsy       16-MAY-07             5.23
Michaels   Matthew     16-MAY-07             5.23
peterson   michael     03-NOV-08             3.77
leblanc    mark        06-MAR-09             3.42
Jeffrey    Thomas      27-FEB-10             2.45
Wong       Theresa     27-FEB-10             2.45

10 rows selected.

 

日付計算には、BETWEEN演算子を使用する方法もあります。この使用例について、リスト16の問合せで示します。注意点として、BETWEEN演算子では、日付範囲の比較において、範囲の最大値の時刻部分として午前0時(00:00:00)が使用されます。日付の比較で範囲の最大値に指定した日付について、可能な値をすべて含めるには、日付範囲の最大値に時刻部分全体を含めるようにしてください。リスト16の例の場合、日付範囲の最大値に27-FEB-2010 23:59:59と指定すれば、結果セット内に、HIRE_DATE値が27-FEB-2010である2人の従業員レコードが含まれるようになります。

コード・リスト16:BETWEEN演算子では、日付範囲の比較で午前0時の時刻が使用される 

SQL> select last_name, first_name, hire_date
  2    from employee
  3   where hire_date BETWEEN TO_DATE('26-FEB-2010', 'DD-MON-YYYY')
  4                       AND TO_DATE('27-FEB-2010', 'DD-MON-YYYY');

FIRST_NAME       LAST_NAME        HIRE_DATE
———————————————  ———————————————  —————————————
Jeffrey          Thomas           27-FEB-10

1 row selected.

 

結論

この記事では、よく使用される日付関数の一部と、それらの関数を使用してデータの表示を操作する方法について説明しました。変換関数のTO_CHARとTO_DATEを使用する方法や、これらの違いについて確認しました。また、すべての日付には時刻部分が含まれ、必要に応じて時刻部分を利用することも切り捨てることもできることがわかりました。SYSDATE関数と日付計算についても紹介しました。最後に重要なこととして、WHERE句内でTO_DATEやBETWEENを使用してDATEの比較を行う際に気をつけるべき落とし穴や、予期せぬ結果を避けるための対策についても学習しました。この記事ではすべてのOracle Databaseの日付関数やデータ型変換関数を説明していません。詳しくは、数値書式要素および日時関数のドキュメントを確認してください。このSQLの基礎に関する次回の記事では、集計関数について説明します。


Melanie Caffreyの顔写真

Melanie Caffrey
はオラクルの上級開発マネージャーです。Expert PL/SQL Practices for Oracle Developers and DBAs(Apress、2011年)およびExpert Oracle Practices: Oracle Database Administration from the Oak Table(Apress、2010年)の共著者でもあります。

▲ ページTOPに戻る

記事一覧へ戻る