以下の事項は 弊社の一般的な製品の方向性に関する概要を説明するものです また 情報提供を唯一の目的とするものであり いかなる契約にも組み込むことはできません 以下の事項は マテリアルやコード 機能を提供することをコミットメント ' 確約 ( するものではないため 購買決定を行う際の判断材料になさらな

Similar documents
Slide 1

以下の事項は 弊社の一般的な製品の方向性に関する概要を説明するものです また 情報提供を唯一の目的とするものであり いかなる契約にも組み込むことはできません 以下の事項は マテリアルやコード 機能を提供することをコミットメント ( 確約 ) するものではないため 購買決定を行う際の判断材料になさらな

第 2 章 PL/SQL の基本記述 この章では PL/SQL プログラムの基本的な記述方法について説明します 1. 宣言部 2. 実行部 3. 例外処理部

PGECons技術ドキュメントテンプレート Ver.3

5 Q. 結果セットを 1 行飛ばしに FETCH することはできますか A. できません Oracle は必ず結果セットを上から 1 行ずつ FETCH します 6 Q. カーソルを一度にいくつまでオープンできますか A. 初期化パラメータ OPEN_CURSORS で指定したの値までカーソルをオ

今さら聞けない!? Oracle入門 ~前編~

DumpCollection IT Exam Training online / Bootcamp PDF and Testing Engine, study and practice

橡実践Oracle Objects for OLE

アジェンダ はじめに PL/SQLプログラムの計測 PL/SQLコードのチューニングの検討 パフォーマンスを意識したコーディング 2

Oracle 入門 ~ 研修受講後のスキルアップサポート ~ 対応バージョン :Oracle 10gR1 ~ 12cR1 本資料は アシスト Oracle 研修をご受講いただいたお客様からのご質問や 研修ではご案内できなかった情報などを FAQ にまとめたものです 研修受講後のスキルアップの一助とし

アジェンダ ORACLE MASTER Oracle Database 11g 概要 11g SQL 基礎 Ⅰ 試験紹介 ポイント解説 Copyright 2011 Oracle. All rights reserved. 2

ストアドプロシージャ移行調査編

プレポスト【問題】

Microsoft PowerPoint - 3-Forms-Others.ppt

内容 Visual Studio サーバーエクスプローラで学ぶ SQL とデータベース操作... 1 サーバーエクスプローラ... 4 データ接続... 4 データベース操作のサブメニューコンテキスト... 5 データベースのプロパティ... 6 SQL Server... 6 Microsoft

はじめに コースの概要と目的条件分岐の方法や複雑な集計の手法など SQL のコーディングの幅を広げるためのテクニックについて説明します また パフォーマンスを考慮した記述方法や正しい結果を取得するための記述方法などについても あわせて説明します 本コースでは 実践的な SQL の記述手法を広く浅く紹

第 1 章 条件分岐 この章では 条件に応じて処理を分岐する方法について説明します 1. CASE 式で複雑な条件分岐を実現 2. 関数を使用した条件分岐 3. MERGE 文による条件に応じた DML の実行

目次 はじめに... 2 無料トライアルのサインアップ方法... 3 トライアル環境へのアクセス 参考情報

第 2 章 問合せの基本操作 この章では データベースから情報を検索する際に使用する SELECT コマンド および SELECT コマンドと 同時に使用する句について説明します 1. 問合せとは 2. 基本的な問合せ 3. 列の別名 4. 重複行を一意にする 5. 検索行の絞込み 6. 文字パター

Oracle Application Expressの機能の最大活用-インタラクティブ・レポート

1.SqlCtl クラスリファレンス SqlCtl クラスのリファレンスを以下に示します メソッドの実行中にエラーが発生した場合は標準エラー出力にメッセージを出力します (1)Connect() メソッド データベースへ connect 要求を行います boolean Connect(String

実践!Oracle Enterprise Manager を使用した 簡単データベース管理 日本オラクル株式会社製品事業統括テクノロジー製品事業統括本部シニアセールスコンサルタント海老坂恵

Oracle SQL Developerの移行機能を使用したOracle Databaseへの移行

Microsoft PowerPoint - 第5章補足-DB2組み込みSQL.ppt

PA4

Oracle Database 12c

Caché SQL に関するよくある質問

Oracle Web CacheによるOracle WebCenter Spacesパフォーマンスの向上

PL/SQL プログラミング Ⅱ ~ 研修受講後のスキルアップサポート ~ 対応バージョン :Oracle 10gR1 ~ 12cR1 本資料は アシスト Oracle 研修をご受講いただいたお客様からのご質問や 研修ではご案内できなかった情報などを FAQ にまとめたものです 研修受講後のスキルア

前ページからの続き // テキストボックス02 id 属性で取得 // id 属性で取得する場合は一意に決まるので 何番目かの指定は不要 var textbox02elem = document.getelementbyid("text_box02_id"); if ("001" == statee

リレーショナルデータベース入門 SRA OSS, Inc. 日本支社 Copyright 2008 SRA OSS, Inc. Japan All rights reserved. 1

以下の事項は 弊社の一般的な製品の方向性に関する概要を説明するものです また 情報提供を唯一の目的とするものであり いかなる契約にも組み込むことはできません 以下の事項は マテリアルやコード 機能を提供することをコミットメント ( 確約 ) するものではないため 購買決定を行う際の判断材料になさらな

<4D F736F F F696E74202D2091E6358FCD B8F88979D B F2E707074>

NEC COBOL SQL アクセス Server Runtime V1.0 COBOL SQL アクセス Server Runtime V1.0 (1 年間保守付 ) COBOL SQL アクセス Server Runtime V1.0 (1 年間時間延長保守付 ) セットアップカード SL438

Microsoft Word - J-jdev_dba_db_developers.doc

標準化 補足資料

3/7 マイグレーション開発方針 顧客名 0 作成者 根岸正 < プログラム移行方針 > システム名称 A-VX システムマイグレーション作成日 2015/09/01 < COBOL 資産のプログラム移行 > COBOLソース ( メインとCOPYLIB) を入力としてSCC 言語変換ツールにてVB

セットアップカード

今さら聞けない!? Oracle入門 ~後編~

Microsoft Word - Lab5d-DB2組み込みSQL.doc

PowerPoint Presentation

PowerPoint Presentation

intra-mart Accel Platform — TableMaintenance ユーザ操作ガイド   第8版  

プレポスト【問題】

WEBシステムのセキュリティ技術

データベース暗号化ツール「D’Amo」性能検証

Oracle SQL Developer Data Modeler

メール全文検索アプリケーション Sylph-Searcher のご紹介 SRA OSS, Inc. 日本支社技術部チーフエンジニア Sylpheed 開発者 山本博之 Copyright 2007 SRA OSS, Inc. Japan All right

PowerPoint プレゼンテーション

PowerPoint Presentation

intra-mart Accel Platform — TableMaintenance ユーザ操作ガイド   第7版   None


MySQL研修コース & 資格のご案内

Microsoft Word - Android_SQLite講座_画面800×1280

以下の事項は 弊社の一般的な製品の方向性に関する概要を説明するものです また 情報提供を唯一の目的とするものであり いかなる契約にも組み込むことはできません 以下の事項は マテリアルやコード 機能を提供することをコミットメント ( 確約 ) するものではないため 購買決定を行う際の判断材料になさらな

以下の事項は 弊社の一般的な製品の方向性に関する概要を説明するものです また 情報提供を唯一の目的とするものであり いかなる契約にも組み込むことはできません 以下の事項は マテリアルやコード 機能を提供することをコミットメント ( 確約 ) するものではないため 購買決定を行う際の判断材料になさらな

DB12.1 Beta HandsOn Seminar

KeyWeb Creator 概要 What s KeyWeb Creator? 動的なホームページを作成するためのツール!! 従来の Web ページ DB を利用した Web ページ <HTML> <HEAD> <TITLE>show_book</TITLE> </HEAD> <BODY> <DI

Microsoft PowerPoint - Lite10g_SyncArchitecture.ppt

PL/SQLからのオペレーティング・システム・コマンドの実行

第 3 章 メディア障害とバックアップ リカバリ この章では メディア障害の発生に備えたバックアップ方法と 障害時の基本的なリカバリ方法につい て説明します 1. メディア リカバリ概要 2. ファイルの多重化 3. アーカイブ モードの設定 4. バックアップ概要 5. 一貫性バックアップ ( オ

早分かりS2Dao

iNFUSE インフューズ

Slide 1

TALON Tips < カレンダー ( 月別 ) の画面を表示する > 株式会社 HOIPOI 第 1.1 版 p. 1

( ハイブリット型データベース環境 ) プロトタイプ検証結果 第二版 有限会社ツインズ Twinz Co., Ltd 年 7 月 3 日 /15

以下の事項は 弊社の一般的な製品の方向性に関する概要を説明するものです また 情報提供を唯一の目的とするものであり いかなる契約にも組み込むことはできません 以下の事項は マテリアルやコード 機能を提供することをコミットメント ( 確約 ) するものではないため 購買決定を行う際の判断材料になさらな

.NETプログラマー早期育成ドリル ~VB編 付録 文法早見表~


PowerPoint -O80_REP.PDF

[Lab 2]Oracleからの移行を促進する新機能

スクールCOBOL2002

第 5 章 結合 結合のパフォーマンスに影響を与える結合の種類と 表の結合順序について内部動作を交えて 説明します 1. 結合処理のチューニング概要 2. 結合の種類 3. 結合順序 4. 結合処理のチューニングポイント 5. 結合関連のヒント

Microsoft PowerPoint - FormsUpgrade_Tune.ppt

Chapter Two

Oracle ADF 11g入門

Oracle DatabaseとIPv6 Statement of Direction

テキストファイルの入出力1

Microsoft PowerPoint - J-S301167_idx_comp.ppt [互換モード]

クエリの作成が楽になるUDF

領域サイズの見積方法

Warehouse Builderにおける予測分析の使用

ORACLE TUNING PACK 11G

( 目次 ) 1. はじめに 開発環境の準備 仮想ディレクトリーの作成 ASP.NET のWeb アプリケーション開発環境準備 データベースの作成 データベースの追加 テーブルの作成

はじめに コースの概要と目的 Oracle をより効率的に使用するための SQL のチューニング方法について説明します また 索引の有無 SQL の 記述方法がパフォーマンスにどのように影響するのかを実習を通して理解します 受講対象者 アプリケーション開発者 / データベース管理者の方 前提条件 S

以下の事項は 弊社の一般的な製品の方向性に関する概要を説明するものです また 情報提供を唯一の目的とするものであり いかなる契約にも組み込むことはできません 以下の事項は マテリアルやコード 機能を提供することをコミットメント ( 確約 ) するものではないため 購買決定を行う際の判断材料になさらな

Oracle Direct Seminar <Insert Picture Here> 試験対策ポイント解説 Bronze DBA11g 日本オラクル株式会社

Oracle Database 12cでのSQL*LoaderのExpress Modeによるロード

<4D F736F F D20837D815B B838B837A838B835F E836782CC91E391D68EE892692E646F63>

Oracle Un お問合せ : Oracle Data Integrator 11g: データ統合設定と管理 期間 ( 標準日数 ):5 コースの概要 Oracle Data Integratorは すべてのデータ統合要件 ( 大量の高パフォーマンス バッチ ローブンの統合プロセスおよ

Java知識テスト問題

プレポスト【解説】

橡ExCtrlPDF.PDF

Oracle DatabaseとIPv6 Statement of Direction

ORACLE PARTITIONING

ソフトウェア基礎 Ⅰ Report#2 提出日 : 2009 年 8 月 11 日 所属 : 工学部情報工学科 学籍番号 : K 氏名 : 當銘孔太

COBOL EE開発環境 ご紹介資料

intra-mart Accel Platform — IM-共通マスタ スマートフォン拡張プログラミングガイド   初版  

Oracle Direct 無償支援サービス ヒアリング・シート利用手順

アーカイブ機能インストールマニュアル

Transcription:

ここからはじめよう Oracle PL/SQL 入門 日本オラクル株式会社オラクルダイレクトテクニカルサービスグループマスタープリンシパルセールスコンサルタント宇多津真彦

以下の事項は 弊社の一般的な製品の方向性に関する概要を説明するものです また 情報提供を唯一の目的とするものであり いかなる契約にも組み込むことはできません 以下の事項は マテリアルやコード 機能を提供することをコミットメント ' 確約 ( するものではないため 購買決定を行う際の判断材料になさらないで下さい オラクル製品に関して記載されている機能の開発 リリースおよび時期については 弊社の裁量により決定されます Oracle と Java は Oracle Corporation 及びその子会社 関連会社の米国及びその他の国における登録商標です 文中の社名 商品名等は各社の商標または登録商標である場合があります 2

Agenda PL/SQLとは プログラムを作成してみる 例外処理 ストアド プログラム パッケージ機能でライブラリをつくる トランザクション制御 3

PL/SQL とは PL/SQL は SQL の手続き型拡張機能としてオラクル社が提供する言語です SQL はデータの集合を操作するための言語ですが 実際の業務処理 '= ビジネス ロジック ( では手続き型の処理が必要な場合があります Oracle Database の内部で SQL と緊密な連携をおこなうことで効率的に業務処理を実行できます 4

PL/SQL を使うメリット SQL 言語と緊密に統合されており 手続き型の処理を記述可能 SQL で取得した データの塊 ' 集合 ( を PL/SQL により業務上の要望に応じて加工 ' 集合演算とは異なる処理 ( PL/SQL でストアド ファンクションを作成することで SQL 操作の中に複雑な業務ロジックを組み込むことができる 複数のトランザクションを統合し 一連の業務処理をまとめて記述可能 ' バッチ処理を記述 ( Oracle Database のデータ操作をコンパクトに記述できる 例外処理 カプセル化 データ隠ぺいおよびオブジェクト指向のデータ等 プログラミングに必要充分な機能を持つ Oracle Database 上で稼動するので プラットフォームによるプログラミングの差異が無い '= 高い移植性 ( 5

PL/SQL プログラムと I/O PL/SQL プログラムでの情報の流れ Oracle Database に対する操作 端末 ' パラメータ指定 ( 端末 ' 文字列出力 ( Oracle DBMS_OUTPUT パッケージ 'OS に対して直接操作しない ( OS UTL_FILE パッケージ UTL_FILE パッケージ ファイル SQL(SELECT) SQL'DML ( ファイル テーブルテーブル Oracle データファイル DML = INSERT / UPDATE / DELETE 等 6

Agenda PL/SQLとは プログラムを作成してみる 例外処理 ストアド プログラム パッケージ機能でライブラリをつくる トランザクション制御 7

HELLO WORLD プログラム SQL*Plus 上に文字列を出力する ブロック DECLARE' 宣言部 ( str VARCHAR2(30); ' 処理部 ( str := 'HELLO WORLD'; DBMS_OUTPUT.PUT_LINE(str); 変数宣言 : strは変数 VARCHAR2(30) は型変数への値の代入変数の内容を端末へ出力事前定義のストアド プロシージャの実行 ' 他プログラミング言語のライブラリ相当 ( ブロック = プログラムのひとかたまり ~ で囲む 8

HELLO WORLD プログラム SQL*Plus 上に文字列を出力する DECLARE str VARCHAR2(30); str := 'HELLO WORLD'; DBMS_OUTPUT.PUT_LINE(str); % sqlplus scott/tiger SQL> @put_line ファイル内容をバッファに 8 / 読み込むバッファの内容を実行する PL/SQLプロシージャが正常に完了しました 期待通りに表示されない SQL> set serveroutput on SQL> @put_line SQL*Plusの設定 8 / HELLO WORLD PL/SQL プロシージャが正常に完了しました ファイル : put_line.sql SQL> 9

SQL 文を実行する 'DML: INSERT/UPDATE/DELETE など ( そのまま DML 文を記述する DECLARE INSERT INTO emp ( empno, ename )VALUES( 1000, 'Ichiro' ); % sqlplus scott/tiger SQL> @insert_emp 12 / PL/SQL プロシージャが正常に完了しました SQL> SELECT empno,ename FROM emp 2 WHERE empno = 1000; EMPNO ENAME ---------- ---------- 1000 Ichiro SQL> ファイル : insert_emp.sql 10

SQL 文を実行する SELECT: 基本構文とよくある失敗 ' その 1( テーブル emp の件数を取得したい DECLARE SELECT count(*) FROM emp; ファイル : select_cnt_01.sql DECLARE cnt NUMBER(4); SELECT count(*) INTO cnt FROM emp; DBMS_OUTPUT.PUT_LINE(cnt); ファイル : select_cnt_02.sql % sqlplus scott/tiger SQL> @select_cnt_01 6 / SELECT count(*) * 行 3 でエラーが発生しました : ORA-06550: 行 3 列 3: PLS-00428: INTO 句はこの SELECT 文に入ります PL/SQLでは SELECT 文はSQLの内部で利用するか INTO 句を利用して一時的に変数に格納します % sqlplus scott/tiger SQL> set serveroutput on SQL> @select_cnt_02 8 / 12 件数 :12 件 PL/SQLプロシージャが正常に完了しました SQL> 11

SQL 文を実行する SELECT: 基本構文とよくある失敗 ' その 2( テーブル emp ( 複数行存在 ) のカラム内容を取得したい DECLARE str VARCHAR2(10); SELECT ename INTO str FROM emp; DBMS_OUTPUT.PUT_LINE(str); % sqlplus scott/tiger SQL> @select_col_a01 7 / DECLARE * 行 1 でエラーが発生しました : ファイル : select_ename01.sql ORA-01422: 完全フェッチがリクエストよりも多くの行を戻しました ORA-06512: 行 4 DECLARE CURSOR c1 IS SELECT ename FROM emp; str VARCHAR2(10); カーソル定義 カーソルを OPEN OPEN c1; LOOP FETCH c1 INTO str; EXIT WHEN C1%NOTFOUND; データが無くなればループを脱出 DBMS_OUTPUT.PUT_LINE(str); END LOOP; CLOSE c1; カーソルを CLOSE 一件取り出し ファイル : select_ename02.sql 12

レコード単位での処理 テーブルのデータを行毎に処理したい場合 レコードを利用 DECLARE CURSOR c1 IS SELECT empno,ename FROM emp; TYPE emp_rec_type IS RECORD ( empno NUMBER(4), ename VARCHAR2(10) ); emp_rec emp_rec_type; OPEN c1; LOOP FETCH c1 INTO emp_rec; EXIT WHEN C1%NOTFOUND; レコードの定義 定義したレコード型を元にレコード変数を定義 個々のメンバーを フィールド とよぶ DBMS_OUTPUT.PUT(TO_CHAR(emp_rec.empno)); DBMS_OUTPUT.PUT_LINE(' ' emp_rec.ename); END LOOP; CLOSE c1; < レコード変数 >.< フィールド名 > でアクセス可能 13

効果的な変数定義 '%TYPE( %TYPE をつかう テーブル定義が変更されてもソースは修正しなくともよい DECLARE CURSOR c1 IS SELECT empno,ename FROM emp; TYPE emp_rec_type IS RECORD ( empno NUMBER(4), ename VARCHAR2(10) ); emp_rec emp_rec_type; OPEN c1; LOOP FETCH c1 INTO emp_rec; EXIT WHEN C1%NOTFOUND; DECLARE CURSOR c1 IS SELECT empno,ename FROM emp; TYPE emp_rec_type IS RECORD ( empno emp.empno%type, ename emp.ename%type ); emp_rec emp_rec_type; OPEN c1; LOOP FETCH c1 INTO emp_rec; EXIT WHEN C1%NOTFOUND; emp テーブルの empno カラム と同じ型定義 DBMS_OUTPUT.PUT(TO_CHAR(emp_rec.empno)); DBMS_OUTPUT.PUT_LINE(' ' emp_rec.ename); END LOOP; CLOSE c1; DBMS_OUTPUT.PUT(TO_CHAR(emp_rec.empno)); DBMS_OUTPUT.PUT_LINE(' ' emp_rec.ename); END LOOP; CLOSE c1; 14

効果的な変数定義 '%ROWTYPE( %ROWTYPE をつかうとレコード変数定義が簡単になります DECLARE CURSOR c1 IS SELECT empno,ename FROM emp; TYPE emp_rec_type IS RECORD ( empno emp.empno%type, ename emp.ename%type ); emp_rec emp_rec_type; OPEN c1; LOOP FETCH c1 INTO emp_rec; EXIT WHEN C1%NOTFOUND; DBMS_OUTPUT.PUT(TO_CHAR(emp_rec.empno)); DBMS_OUTPUT.PUT_LINE(' ' emp_rec.ename); END LOOP; CLOSE c1; CURSOR c1 IS SELECT empno,ename FROM emp; emp_rec c1%rowtype; カーソル定義をもとにレコード変数を定義 CURSOR c1 IS SELECT empno,ename FROM emp; emp_rec emp%rowtype; テーブル定義をもとにレコード変数を定義 15

参考 ( レコードを利用した挿入と更新 列リストを指定するかわりにレコードを指定できます DECLARE emp_rec emp%rowtype; emp_rec.empno := 1000; emp_rec.ename := 'Ichiro'; INSERT INTO emp ( empno, ename )VALUES( emp_rec.empno, emp_rec.ename ); 通常のINSERT 構文 DECLARE emp_rec emp%rowtype; emp_rec.empno := 1000; emp_rec.ename := 'Ichiro'; INSERT INTO emp VALUES emp_rec; INSERTの拡張構文 DECLARE emp_rec emp%rowtype; emp_rec.empno := 1000; emp_rec.ename := 'Ichiro01'; emp_rec.deptno := 10; UPDATE emp SET ename = emp_rec.ename, deptno = emp_rec.deptno WHERE empno = emp_rec.empno; 通常の UPDATE 構文 DECLARE emp_rec emp%rowtype; emp_rec.empno := 1000; emp_rec.ename := 'Ichiro01'; emp_rec.deptno := 10; UPDATE emp SET ROW = emp_rec WHERE empno = emp_rec.empno; UPDATE の拡張構文 16

Agenda PL/SQLとは プログラムを作成してみる 例外処理 ストアド プログラム パッケージ機能でライブラリをつくる トランザクション制御 17

例外処理とは 例外 'PL/SQL 実行時エラー ( が発生してもプログラムで処理を継続できるようにすることができます DECLARE DECLARE 例外が発生すると例外処理部へ遷移 処理 1 処理 1 ブロック 処理 2 処理 2 例外 処理 3 EXCEPTION 例外処理部 WHEN OTHERS THEN 例外処理 処理 3 処理されない EXCEPTION WHEN OTHERS THEN 例外処理 18

ブロックの入れ子と例外処理 入れ子のブロックできめ細かな例外処理が可能です DECLARE 処理 1 例外処理 2 EXCEPTION WHEN OTHERS THEN RAISE; 外側のブロックの例外処理部へ 処理 3 処理されない EXCEPTION WHEN OTHERS THEN 例外処理 DECLARE 処理 1 例外処理 2 EXCEPTION WHEN OTHERS THEN NULL; 例外を無視 処理 3 処理される EXCEPTION WHEN OTHERS THEN 例外処理 19

特定の例外を捕捉する 特定の例外を捕捉し 例外に応じた処理をおこないます DECLARE INSERT INTO emp (empno,ename) VALUES (1000,'Ichiro'); INSERT INTO emp (empno,ename) VALUES (1000,'Ichiro 2'); EXCEPTION WHEN DUP_VAL_ON_INDEX THEN UPDATE emp SET ename = 'Ichiro 2' WHERE empno = 1000; WHEN OTHERS THEN NULL; EXCEPTION WHEN OTHERS THEN キー重複エラーを捕捉 DBMS_OUTPUT.PUT_LINE('Error'); ファイル : ins_upd_emp01.sql SQL> @ins_upd_emp 20 / PL/SQL プロシージャが正常に完了しました SQL> SELECT empno,ename FROM emp 2 WHERE empno = 1000; EMPNO ENAME ---------- ---------- 1000 Ichiro 2 SQL> よく利用される例外は事前定義例外として提供されています 20

捕捉した例外情報を表示 SQLERRM SQLCODE を利用してエラー情報を取得します DECLARE -- emp 表の empno カラムは NUMBER(4) INSERT INTO emp ( empno, ename ) VALUES ( 10000, 'Ichiro*10' ); EXCEPTION WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE( SQLERRM ); DBMS_OUTPUT.PUT_LINE( SQLCODE ); ファイル : insert_emp_err01.sql SQL> @insert_emp_err01 18 / ORA-01438: この列に許容される指定精度より大きな値です -1438 PL/SQL プロシージャが正常に完了しました SQL> 21

ユーザ独自の例外定義 例外を定義して 例外処理部で独自にハンドリングできます RAISE_APPLICATION_ERROR を利用して例外を発生させます DECLARE usr_excp EXCEPTION; usr_excp_num NUMBER := -20001; usr_excp_str VARCHAR2(30) := 'User Exception'; PRAGMA EXCEPTION_INIT(usr_excp, -20001); RAISE_APPLICATION_ERROR( usr_excp_num, エラー コードを指定 usr_excp_str ); SQL> @raise_appl_err01 20 / ORA-20001: User Exception -20001 メッセージ取得可能 PL/SQLプロシージャが正常に完了しました SQL> EXCEPTION WHEN usr_excp THEN DBMS_OUTPUT.PUT_LINE( SQLERRM ); DBMS_OUTPUT.PUT_LINE( SQLCODE ); WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE('Error'); ファイル : raise_appl_err01.sql ユーザが利用できるエラー番号の範囲 : -20000 から -20999 まで エラー メッセージは 2048Byte 以内 22

参考 ( ユーザ定義例外の RAISE RAISE ではエラーメッセージを取得できません DECLARE usr_excp EXCEPTION; usr_excp_num NUMBER := -20001; usr_excp_str VARCHAR2(30) := 'User Exception'; PRAGMA EXCEPTION_INIT(usr_excp, -20001); RAISE usr_excp; EXCEPTION WHEN usr_excp THEN DBMS_OUTPUT.PUT_LINE( SQLERRM ); DBMS_OUTPUT.PUT_LINE( SQLCODE ); WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE('Error'); ファイル : raise_appl_err02.sql SQL> @raise_appl_err02 17 / ORA-20001: -20001 PL/SQL プロシージャが正常に完了しました SQL> メッセージが取得できない RAISE にユーザ定義例外を指定するのみ エラーメッセージが取得できない為 エラーハンドリングを検討する必要があります 23

Agenda PL/SQLとは プログラムを作成してみる 例外処理 ストアド プログラム パッケージ機能でライブラリをつくる トランザクション制御 24

ストアド プログラム ストアド プロシージャ PL/SQLで記述した一連の処理手続きに名前をつけ Oracle Database に格納したもの DECLARE ストアド ファンクション CREATE PROCEDURE proc IS プロシージャ作成 PL/SQLで記述した なんらかの値を返却する処理手続きに名前をつけ Oracle Databaseに格納したもの DECLARE IF cnt > 20 THEN END IF; DECLARE IF func(cnt,20) THEN END IF; CREATE FUNCTION func (p1 NUMBER, p2 NUMBER) RETURN BOOLEAN IS IF p1 > p2 THEN RETURN TRUE; END IF; RETURN FALSE; ファンクション作成 25

プロシージャとファンクションの使い分け プロシージャ バッチ処理などの一連の処理手続きはプロシージャにて実装 プロシージャ内部で INSERT/UPDATE/DELETE を実施 エラーを例外にて捕捉でき 必要に応じて処理を取り消す 'ROLLBACK( ことができる ファンクション パラメータにて渡された値の判定 変換処理 値の抽出をおこなう 一般的にファンクション内部では INSERT/UPDATE/DELETE を実施しない エラーは例外で捕捉するものの例外処理は行なわず エラーが発生したことを示す値を返却することが多い SQL 文中で利用することが可能 ' 一部例外あり ( 26

ファンクションをつくる 値の抽出 値の変換などをおこなう例 CREATE OR REPLACE FUNCTION get_sales_tax(date_in IN DATE) RETURN NUMBER IS tax sales_tax.tax%type; SELECT tax INTO tax FROM sales_tax WHERE FROM_DATE <= date_in AND TO_DATE >= date_in; RETURN tax; EXCEPTION WHEN OTHERS THEN RETURN NULL; 例外発生時は NULL を戻す テーブルより特定情報を取得 CREATE OR REPLACE FUNCTION get_quarter(date_in IN DATE) RETURN NUMBER IS mm_str VARCHAR2(2); mm_str := TO_CHAR(date_in,'MM'); CASE mm_str WHEN '01' THEN RETURN 3; WHEN '02' THEN RETURN 3; WHEN '03' THEN RETURN 4; WHEN '04' THEN RETURN 4; WHEN '05' THEN RETURN 4; WHEN '06' THEN RETURN 1; WHEN '07' THEN RETURN 1; WHEN '08' THEN RETURN 1; WHEN '09' THEN RETURN 2; WHEN '10' THEN RETURN 2; WHEN '11' THEN RETURN 2; WHEN '12' THEN RETURN 3; ELSE END CASE; EXCEPTION WHEN OTHERS THEN RETURN NULL; RETURN NULL; 例外発生時は NULL を戻す 値の変換 27

参考 ( 内部で SELECT をおこなうファンクション ファンクション内部でSELECTを実施しており データ量によってはパフォーマンスが悪くなることがあります SELECT FROM tbl1 WHERE col1 > get_price(item_id, sysdate-60) ; CREATE FUNCTION get_price (item_id_in IN NUMBER, dt_in IN DATE) RETURN NUMBER IS ret_num NUMBER; SELECT price INTO ret_num FROM price_list WHERE item_id = item_id_in AND from_dt <= TRUNC(dt_in) AND to_dt > TRUNC(dt_in) ; RETURN ret_num; END get_price; 対処案 1( ファンクションの利用をやめ 結合処理に作り直す 対処案 2(PL/SQL ファンクションの結果キャッシュを利用する 28

参考 ( 内部で SELECT をおこなうファンクション PL/SQL ファンクションの結果キャッシュ '11g R1~ Enterprise Edition( PL/SQL ファンクションの結果を SGA にキャッシュし 複数のセッションで利用できます ファンクションおよびパラメータの値を組にして結果をキャッシュ システムで必要なメモリが足りなくなると古いものから破棄 ファンクション内で参照している表が変更されるとキャッシュは破棄 CREATE OR REPLACE FUNCTION get_price(item_id_in IN NUMBER, dt_in IN DATE) RETURN NUMBER RESULT_CACHE RELIES_ON ( price_list ) IS ret_num NUMBER; SELECT price INTO ret_num FROM price_list WHERE item_id = item_id_in AND from_dt <= TRUNC(dt_in) 11g R2 からは RELIES_ON 記述は不要 AND to_dt > TRUNC(dt_in) ; RETURN ret_num; END get_price; 29

Agenda PL/SQLとは プログラムを作成してみる 例外処理 ストアド プログラム パッケージ機能でライブラリをつくる トランザクション制御 30

パッケージ機能でライブラリをつくる パッケージとは 論理的に関連する PL/SQL の型 変数およびサブプログラムをまとめる為のスキーマ オブジェクト パッケージの利点 モジュール性 アプリケーション共通で利用するものを一元管理 情報の隠蔽 サブプログラムのオーバーロード機能 オブジェクトの永続性 31

パッケージのモジュール性 アプリケーション共通で利用するものを一元管理できます パッケージ仕様部に記述します 定数 ' アプリ利用のマジックナンバー ( 例外 カーソル 型 ' レコード ( CREATE OR REPLACE PACKAGE xxx IS 外部公開のオブジェクト定義外部公開のサブプログラム仕様 END xxx; パッケージ仕様部 他のアプリケーションから実行されたくないサブプログラムなどを隠蔽できます パッケージ本体のみに記述します パッケージ内のみ利用可能なプライベート変数も定義できます CREATE OR REPLACE PACKAGE BODY xxx IS END xxx; パッケージ内プライベート変数 パッケージ内のみ利用可能な サブプログラム 外部公開のサブプログラム本体 パッケージ本体 32

パッケージをつくる CREATE OR REPLACE PACKAGE pkg IS PROCEDURE p (p_in IN VARCHAR2); FUNCTION f_n (p_in IN NUMBER) RETURN NUMBER; FUNCTION f_c (p_in IN VARCHAR2) RETURN VARCHAR2; ファイル ' パッケージ仕様部 (: pkg01.pks CREATE OR REPLACE PACKAGE BODY pkg IS PROCEDURE p(p_in IN VARCHAR2)IS DBMS_OUTPUT.PUT_LINE(p_in); END p; FUNCTION f_n (p_in IN NUMBER) RETURN NUMBER IS RETURN p_in; END f_n; FUNCTION f_c (p_in IN VARCHAR2) RETURN VARCHAR2 IS RETURN p_in; END f_c; ファイル ' パッケージ本体 (: pkg01.pkb SQL> @pkg01.pks 8 / パッケージが作成されました SQL> @pkg01.pkb 17 / パッケージ本体が作成されました SQL> execute pkg.p('test') test PL/SQL プロシージャが正常に完了しました SQL> select pkg.f_n(100) from dual; PKG.F_N(100) ------------ 100 プロシージャを SQL*Plus で 実行する際は execute にて指定 SQL> select pkg.f_c('test') from dual; PKG.F_C('TEST') --------------------------------- test 33

オーバーロード同じ名前 ' 引数の数 順序 型は異なる ( のサブプログラムを定義 CREATE OR REPLACE PACKAGE pkg IS PROCEDURE p (p_in IN VARCHAR2); FUNCTION p (p_in IN NUMBER) RETURN NUMBER; FUNCTION p (p_in IN VARCHAR2) RETURN VARCHAR2; ファイル ' パッケージ仕様部 (: pkg01.pks CREATE OR REPLACE PACKAGE BODY pkg IS PROCEDURE p(p_in IN VARCHAR2)IS DBMS_OUTPUT.PUT_LINE(p_in); END p; FUNCTION p(p_in IN NUMBER) RETURN NUMBER IS RETURN p_in; END p; FUNCTION p(p_in IN VARCHAR2) RETURN VARCHAR2 IS RETURN p_in; END p; ファイル ' パッケージ本体 (: pkg01.pkb SQL> @pkg02.pks 8 / パッケージが作成されました SQL> @pkg02.pkb 17 / パッケージ本体が作成されました SQL> execute pkg.p('test') test PL/SQL プロシージャが正常に完了しました SQL> select pkg.p(100) from dual; PKG.P(100) ------------ 100 SQL> select pkg.p('test') from dual; PKG.P('TEST') --------------------------------- test 適切に選択される 34

パッケージオブジェクトの永続性 パッケージで定義されている変数の変更は セッションが切れるまで有効です セッションが同じであれば 複数のトランザクション ' 後述 ( 間で グローバル変数 のように利用可能 例 ) 同一セッションで アプリ基準日付 を使いまわしたい テーブルへのアクセスは セッション開始後の初回実行時のみ CREATE OR REPLACE PACKAGE BODY base_date IS /* プライベート変数 */ p_base_date DATE := NULL; FUNCTION get_base_date RETURN DATE IS IF p_base_date IS NOT NULL THEN dbms_output.put_line('no select'); RETURN p_base_date; END IF; SELECT app_date INTO p_base_date FROM CONTROL_MST WHERE id = 2; RETURN p_base_date; EXCEPTION アプリ基準日付 WHEN OTHERS THEN の取得 RETURN NULL; END get_base_date; END base_date; 35

参考 ( パッケージの初期化部 パッケージ本体に初期化部を記述することもできます CREATE OR REPLACE PACKAGE BODY base_date IS /* プライベート変数 */ p_base_date DATE := NULL; FUNCTION get_base_date RETURN DATE IS IF p_base_date IS NOT NULL THEN dbms_output.put_line('no select'); RETURN p_base_date; END IF; SELECT app_date INTO p_base_date FROM CONTROL_MST WHERE id = 2; RETURN p_base_date; EXCEPTION WHEN OTHERS THEN RETURN NULL; END get_base_date; END base_date; CREATE OR REPLACE PACKAGE BODY base_date IS /* プライベート変数 */ p_base_date DATE := NULL; FUNCTION get_base_date RETURN DATE IS RETURN p_base_date; END get_base_date; SELECT app_date INTO p_base_date FROM CONTROL_MST WHERE id = 2; EXCEPTION WHEN OTHERS THEN p_base_date := NULL; END base_date; 初期化部 パッケージのインスタンス化時に 1 回だけ実行 36

Aganda PL/SQLとは プログラムを作成してみる 例外処理 ストアド プログラム パッケージ機能でライブラリをつくる トランザクション制御 37

トランザクション管理 トランザクション = 分割できない一連の情報処理の単位 10 万円の銀行振込を行う場合 自分の口座の金額確認一つのト自分の口座を減額 '-10 万円 ( ランザ振り込み先口座を増額 '+10 万円 ( クショデータ更新確定ン ' コミット ( 更新処理を全て元に戻す ( ロールバック ) 障害発生 38

トランザクションの制御 Oracle Database では DML 文や DDL 文が最初に実行された時からトランザクションが開始される ' 宣言は不要 ( 処理 1 処理 2 通常 処理部の最後に COMMIT 例外処理部分に ROLLBACK COMMIT; EXCEPTION WHEN OTHERS THEN ROLLBACK; トランザクションとして制御したい単位でストアド プロシージャ ' 後述 ( に分割します 39

トランザクションの制御 ' バッチ的な処理 ( エラーが発生した時に 再実行可能な単位でトランザクションを制御 ' コミット / ロールバック ( する 開始 すべての処理が正常終了するまでコミットしない 再実行可能な単位をどこに設定するのか? 処理 1 処理 2 COMMIT? 処理 1-1 処理 1-2 処理 2-1 処理 2-2 エラーが発生するとすべてをロールバックし エラー原因を対処し 再実行 処理単位毎にコミットする 処理がどこまで正常に終了しているかを記録しておく必要がある 終了 処理 3 処理 3-1 処理 3-2 再実行時には正常終了部分の処理はスキップする処理を組み込む PL/SQL で作成するジョブの単位を適切に検討する 40

自律型トランザクション 実行中のトランザクションとは別の独立したトランザクションのサブプログラムを呼び出すことができます メイントランザクションがロールバックしてもログなどを取得できます 自律型トランザクション側でコミットした情報を別のトランザクションからすぐに確認できます PROCEDURE proc_a IS INSERT INTO table_a VALUES ; proc_b; ' メイン トランザクション中断 ( ' メイン トランザクション再開 ( ROLLBACK; ロールバックされる PROCEDURE proc_b IS PRAGMA AUTONOMOUS_TRANSACTION; INSERT INTO table_b VALUES ; COMMIT; ' トランザクション終了 ( 自律型トランザクションの宣言 ' トランザクション開始 ( ロールバックされない 41

参考 ( バッチプログラムを作成するときの Tips 複数の SQL を単一のブロックにいれない 必ず例外処理部でエラー処理をおこなう ブロック毎に名前をつけて パッケージ変数に名前をセット エラーが発生するとパッケージ変数にエラー情報をセット 最上位ブロックの例外処理部では上記のパッケージ変数を出力することでエラー発生箇所を特定 sub_main01(); sub_main02(); EXCEPTION WHEN OTHERS THEN dbms_output.put_line(err.proc); dbms_output.put_line(err.errcd); IF is_execute() THEN RETURN; END IF; proc01(); proc02(); COMMIT; EXCEPTION WHEN OTHERS THEN ROLLBACK; RAISE; 一度正常実行されたら処理をスキップ err.proc := 'proc01'; /* SQL 処理 */ EXCEPTION WHEN OTHERS THEN err.errcd := SQLCODE; RAISE; 42

まとめ PL/SQL により Oracle Database の内部で効率的に業務処理を実行できます ストアド プログラムを使い業務ロジックを作成することで Oracle Database 利用者は業務ロジックを共用することができます 例外処理 トランザクション処理 パッケージ機能の特性など PL/SQL を利用する上で知っておくべきことを解説しました 43

Appendix よくつかう SQL*Plus の機能 SQL*Plusとは SQLスクリプトの実行 SQLスクリプト内の文字列置換 SQL*Plusの表示機能 表示内容のファイルへの保存 SQL*Plusバインド変数の使用と値の表示 SQLスクリプト終了時にOSにエラーを返却 44

SQL*Plus とは SQL*Plus は Oracle Database へのコマンドライン ユーザ インターフェースであり 以下のようなことができます Oracle Database の管理 表定義およびオブジェクト定義の検証 Oracle Database へのバッチ処理スクリプトの開発および実行 問い合わせ結果の書式設定 計算の実行 45

SQL スクリプトの実行 定型処理は SQL*Plus で実行可能な SQL や PL/SQL をテキストファイルにひとつにまとめたものを SQL スクリプトとして実行します SQL*Plus コマンドラインにて指定 % sqlplus username/[password] @< ファイル名 [. 拡張子 ]> < パラメータ > SQL*Plus で Oracle Database に接続した後に指定 % sqlplus username/[password] SQL> start < ファイル名 [. 拡張子 ]> < パラメータ > SQL> @< ファイル名 [. 拡張子 ]> < パラメータ > パラメータを利用する際には SQL スクリプトファイル中にて &1 および &2 のような置換変数 ' 後述 ( を利用します 46

SQL スクリプト内の文字列置換 置換変数 : 任意の変数の前に '&' もしくは '&&' をつけたもの select '&pswd01' from dual; select '&&pswd02' from dual; ファイル : replace01.sql 単一 & 置換変数はスクリプト中で出現する度に入力を促す 二重 & 置換変数は スクリプト中の初回は入力を促すが 後続の変数では初回と同じ値を利用する ' 何回も問い合わせてこない ( SQL> @replace01 pswd01に値を入力してください : test1 旧 1: select '&pswd01' from dual 新 1: select 'test1' from dual SQL> @replace01 pswd01に値を入力してください : test-001 旧 1: select '&pswd01' from dual 新 1: select 'test-001' from dual 'TEST ----- test1 'TEST-00 -------- test-001 入力を促さない pswd02に値を入力してください : test2 旧 1: select '&&pswd02' from dual 新 1: select 'test2' from dual 'TEST ----- test2 1 回目実行 旧新 'TEST ----- test2 1: select '&&pswd02' from dual 1: select 'test2' from dual '1 回目に続けて ( 2 回目実行 47

SQL*Plus の表示機能 ' その 1( SQL*Plus の代表的な表示設定 ページ設定 SET PAGES[IZE] {14 n} 1 行の長さ SET LIN[ESIZE] {80 n} レポートの列ヘッダ情報の出力有無 レポートの列ヘッダーのアンダーラインで利用する文字 数値のフォーマット SET HEA[DING] {ON OFF} SET UND[ERLINE] {- c ON OFF} SET NUMF[ORMAT] format 数値のデフォルト桁 SET NUM[WIDTH] {10 n} NULL 値を表す文字列 画面出力の制御 端末出力の行末スペース削除 ファイル出力時の行末スペース削除 実行結果の表示 列セパレータの指定 SET NULL text SET TERM[OUT] {ON OFF} SET TRIM[OUT] {ON OFF} SET TRIMS[POOL] {ON OFF} SET FEED[BACK] {6 n ON OFF} SET COLSEP { text} PAGESIZE LINESIZE HEADING UNDERLINE <NULL> NULL xx 行が選択されました FEEDBACK NUMWIDTH 99,999,999 NUMFORMAT 48

SQL*Plus の表示機能 ' その 2( 列の書式設定 COLUMN コマンドで設定 列の書式設定 数値型 文字列型 日付型 : column < カラム名 > format < 書式 > SQL> column sal format 99,999,999 column < カラム名 > format a< 長さ > 必要に応じて SQL 文上で TO_CHAR 等を利用して文字列型に SQL> select * from emp where empno = 7900; EMPNO ENAME JOB MGR HIREDATE SAL COMM ---------- ---------- --------- ---------- -------- ---------- ---------- DEPTNO ---------- 7900 JAMES CLERK 7698 81-12-03 950 30 SQL> column ename format a10 読みにくい SQL> column empno format 9999 SQL> column mgr format 9999 SQL> column sal format 000,009 SQL> select * from emp where empno = 7900; EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO ----- ---------- --------- ----- -------- -------- ---------- ---------- 7900 JAMES CLERK 7698 81-12-03 000,950 30 数値型のデフォルトの 桁長は 10 桁 49

表示内容のファイルへの保存 SPOOL コマンドを利用して実行結果を保存する SQL> spool c: temp emp.txt SQL> select ename from emp 2 where empno = 7900; D: > type emp7900.sql select ename from emp where empno = 7900; ENAME ---------- JAMES SQL> spool off SQL> exit D: > D: > type c: temp emp.txt SQL> select ename from emp 2 where empno = 7900; ENAME ---------- JAMES SQL> spool off D: > 作成されるファイルは LINESIZE までスペース詰されているので 不要時は SET TRIMSPOOL ON を設定 D: > sqlplus scott/tiger ( 略 ) SQL> set termout off SQL> spool c: temp emp7900.txt SQL> @emp7900 SQL> spool off 画面に表示されない SQL> exit ( 略 ) D: > type c: temp emp7900.txt SQL> @emp7900 ENAME ---------- JAMES SQL> spool off D: > SQL スクリプトが作成済みで 出力内容を画面に表示したくない場合は SET TERMOUT OFF を設定する 50

SQL*Plus バインド変数の使用と値の表示 バインド変数は SQL*Plusで作成し PL/SQLおよびSQL で参照することのできる変数 VARIABLE で設定し 表示は PRINT でおこないます 複数のスクリプト間で変数の受け渡しができます VARIABLE ret_val NUMBER :ret_val := 0; / @val01.sql PRINT ret_val @val01.sql PRINT ret_val ファイル : val00.sql :ret_val := :ret_val + 4; / ファイル : val01.sql SQL> @val00 PL/SQL プロシージャが正常に完了しました PL/SQL プロシージャが正常に完了しました RET_VAL ---------- 4 PL/SQL プロシージャが正常に完了しました RET_VAL ---------- 8 SQL> 51

SQL スクリプト終了時に OS にエラーを返却 EXIT および WHENEVER SQLERROR を利用する WHENEVER SQLERROR EXIT SQL.SQLCODE ROLLBACK SELECT * FROM &tname WHERE empno = 9999; EXIT 0 ファイル : exit01.sql D: > sqlplus -s scott/tiger @exit01 tname に値を入力してください : emp 旧 1: SELECT * FROM &tname 新 1: SELECT * FROM emp レコードが選択されませんでした D: > echo %errorlevel% 0 D: > sqlplus -s scott/tiger @exit01 tnameに値を入力してください : em 旧 1: SELECT * FROM &tname 存在しない新 1: SELECT * FROM em SELECT * FROM em テーブル名 * 行 1でエラーが発生しました : ORA-00942: 表またはビューが存在しません D: > echo %errorlevel% 942 SQL.SQLCODE は UNIX 系 OS では終了コードが 1byte しかないので 256 で割った余りを返します 'KROWN#10025 ( 52

OTN セミナーオンデマンド コンテンツに対するご意見 ご感想を是非お寄せください OTN オンデマンド感想 http://blogs.oracle.com/oracle4engineer/entry/otn_ondemand_questionnaire 上記に簡単なアンケート入力フォームをご用意しております セミナー講師 / 資料作成者にフィードバックし コンテンツのより一層の改善に役立てさせていただきます 是非ご協力をよろしくお願いいたします 53

OTN セミナーオンデマンド日本オラクルのエンジニアが作成したセミナー資料 動画ダウンロードサイト 掲載コンテンツカテゴリ ( 一部抜粋 ) Database 基礎 Database 現場テクニック Database スペシャリストが語る Java WebLogic Server/ アプリケーション グリッド EPM/BI 技術情報サーバーストレージ 100 以上のコンテンツをログイン不要でダウンロードし放題 データベースからハードウェアまで充実のラインナップ 毎月 旬なトピックの新作コンテンツが続々登場 例えばこんな使い方 製品概要を効率的につかむ 基礎を体系的に学ぶ / 学ばせる 時間や場所を選ばず ' オンデマンド ( に受講 スマートフォンで通勤中にも受講可能 毎月チェック! コンテンツ一覧はこちら http://www.oracle.com/technetwork/jp/ondemand/index.html 新作 & おすすめコンテンツ情報はこちら http://oracletech.jp/seminar/recommended/000073.html OTN オンデマンド 54

オラクルエンジニア通信オラクル製品に関わるエンジニアの方のための技術情報サイト 技術資料 インストールガイド 設定チュートリアル etc. 欲しい資料への最短ルート アクセスランキング 他のエンジニアは何を見ているのか? 人気資料のランキングは毎月更新 特集テーマ Pick UP 性能管理やチューニングなど月間テーマを掘り下げて詳細にご説明 技術コラム SQL スクリプト 索引メンテナンス etc. 当たり前の運用 / 機能が見違える!? http://blogs.oracle.com/oracle4engineer/ オラクルエンジニア通信 55

oracletech.jp IT エンジニアの皆様に向けて旬な情報を楽しくお届け 製品 / 技術情報 Oracle Database っていくら? オプション機能も見積れる簡単ツールが大活躍 セミナー 基礎から最新技術までお勧めセミナーで自分にあった学習方法が見つかる スキルアップ ORACLE MASTER! 試験頻出分野の模擬問題と解説を好評連載中 Viva! Developer 全国で活躍しているエンジニアにスポットライト きらりと輝くスキルと視点を盗もう http://oracletech.jp/ oracletech 56

あなたにいちばん近いオラクル Oracle Direct まずはお問合せください Oracle Direct システムの検討 構築から運用まで IT プロジェクト全般の相談窓口としてご支援いたします ステム構成やライセンス / 購入方法などお気軽にお問い合わせ下さい Web 問い合わせフォーム 専用お問い合わせフォームにてご相談内容を承ります http://www.oracle.co.jp/inq_pl/inquiry/quest?rid=28 フリーダイヤル 0120-155-096 フォームの入力にはログインが必要となります こちらから詳細確認のお電話を差し上げる場合がありますので ご登録の連絡先が最新のものになっているかご確認下さい 月曜 ~ 金曜 9:00~12:00 13:00~18:00 ' 祝日および年末年始除く ( 57

58