PL/SQLをOracle19で使ってみた
目次
ストアドプロシージャーでDB処理
仕事先で偶然にかち合いました。ストアドプロシージャー。
プログラムのリプレース(古いプログラムの機能を新しく書き直したプログラムで置き換えること)作業で、参画時のブリーフィングで使っていると聞きましたが、私はPL/SQLに触れるのははじめてです。
せっかく仕事で触れる機会があったのだから、自分のスキルにしてしまおうという魂胆です(w)
PL/SQL開発の準備
まずは、PL/SQLが実装できる環境を用意しましょう。
Oracleの実行環境
今回は、以前にインストール関係の記事を書いたOracleの環境が残っていたため、それをそのまま使用します。
インストールと環境設定
このとき、サンプルスキーマとして、HRもインストールしましたので、それを使用して作成していきます。
Oracleデータベース起動
インストールは完了していますので、Oracleデータベースを起動します。
sqlplus / as sysdba で、sysdbaユーザーでログインし、起動コマンドを入力するのですが……
[oracle@oracledb ~]$ sqlplus / as sysdba
SQL*Plus: Release 19.0.0.0.0 - Production on Wed Jun 29 17:05:21 2022
Version 19.3.0.0.0
Copyright (c) 1982, 2019, Oracle. All rights reserved.
Connected to an idle instance.
SQL> STARTUP
ORACLE instance started.
Total System Global Area 2415917880 bytes
Fixed Size 8899384 bytes
Variable Size 553648128 bytes
Database Buffers 1845493760 bytes
Redo Buffers 7876608 bytes
?????????????????
?????????????????
SQL>
ん?文字化けしますね。
oracle Linux oracle sqlplus linux 文字化け でGoogle検索したところ、こちらのサイト様がヒットしました。
こちらの記事どおり、vi .bash_profile でファイルを開き、export NLS_LANG=Japanese_Japan.AL32UTF8 を追記して再起動したら……
[oracle@oracledb ~]$ sqlplus / as sysdba
SQL*Plus: Release 19.0.0.0.0 - Production on 水 6月 29 17:15:09 2022
Version 19.3.0.0.0
Copyright (c) 1982, 2019, Oracle. All rights reserved.
アイドル・インスタンスに接続しました。
SQL> STARTUP
ORACLEインスタンスが起動しました。
Total System Global Area 2415917880 bytes
Fixed Size 8899384 bytes
Variable Size 553648128 bytes
Database Buffers 1845493760 bytes
Redo Buffers 7876608 bytes
データベースがマウントされました。
データベースがオープンされました。
SQL>
いや本当に待ってくださいよ。CentOSにOracle12cをインストールしたときのお話ですよ?これ。
こちらのはOracle Linuxなんですよ? それにOracle19.3をインストールしているっていうのに、日本語処理すら解決できてなくて、ユーザーに記述変更させるんですか?
気を取り直し、リスナーも繋ぎます。
$ lsnrctl start
LSNRCTL for Linux: Version 19.0.0.0.0 - Production on 29-6月 -2022 17:25:51
Copyright (c) 1991, 2019, Oracle. All rights reserved.
/u01/app/oracle/product/19.3.0/dbhome_1/bin/tnslsnrを起動しています。お待ちください...
TNSLSNR for Linux: Version 19.0.0.0.0 - Production
システム・パラメータ・ファイルは/u01/app/oracle/product/19.3.0/dbhome_1/network/admin/listener.oraです。
ログ・メッセージを/u01/app/oracle/diag/tnslsnr/oracledb/listener/alert/log.xmlに書き込みました。
リスニングしています: (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=oracledb)(PORT=1521)))
リスニングしています: (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC1521)))
(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=oracledb)(PORT=1521)))に接続中
リスナーのステータス
------------------------
別名 LISTENER
バージョン TNSLSNR for Linux: Version 19.0.0.0.0 - Production
開始日 29-6月 -2022 17:25:52
稼働時間 0 日 0 時間 0 分 0 秒
トレース・レベル off
セキュリティ ON: Local OS Authentication
SNMP OFF
パラメータ・ファイル /u01/app/oracle/product/19.3.0/dbhome_1/network/admin/listener.ora
ログ・ファイル /u01/app/oracle/diag/tnslsnr/oracledb/listener/alert/log.xml
リスニング・エンドポイントのサマリー...
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=oracledb)(PORT=1521)))
(DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC1521)))
リスナーはサービスをサポートしていません。
コマンドは正常に終了しました。
続いて、sqlplusでサンプルスキーマのHRにログインしてみます。
$ sqlplus HR/HR
SQL*Plus: Release 19.0.0.0.0 - Production on 水 6月 29 17:28:00 2022
Version 19.3.0.0.0
Copyright (c) 1982, 2019, Oracle. All rights reserved.
最終正常ログイン時間: 火 6月 28 2022 13:23:42 +09:00
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.3.0.0.0
に接続されました。
SQL>
いろいろ思うところはありますが、とりあえずOracleデータベースを起動し、sqlplusの起動環境までは確保できました。
参考
少し古い本ですが、こちらを参考にしました。
本の環境は、Oracle12cでの実行を前提としていまして、インストールについても書かれていますが、現状、Oracle12cを入手する事は難しいので、19cで行う事にします。
また、書籍ではWindows環境でのプログラム作成などを前庭としてますが、実行はこのとき構築したOracle Linux 上で行う事とします。
最初の一歩/HelloWorld
プログラムの勉強は、まずは何はなくともHelloWorldと表示してみるところから始まります。
PL/SQLはSQLですが、手続き型プログラム言語であるため、HelloWorldを表示するプログラムが書けます。
参考にした「基礎からわかる PL/SQL」から、最初のPL/SQLを記述してみます。
SQL> SET SERVEROUTPUT ON
SQL> BEGIN
2 DBMS_OUTPUT.PUT_LINE('HELLO WORLD');
3 END;
4 /
HELLO WORLD
PL/SQLプロシージャが正常に完了しました。
SQL>
最初のSET SERVEROUTPUT ON は、sqlplusでログインしたとき、一回実行すればOKとの事です。
DBMS_OUTPUT.PUT_LINE が、PL/SQLでは標準出力に出力するコマンドで、正常にHELLO WORLDが出力されました。
ファイルから実行する
最初のPL/SQLは、sqlplusの画面に直接記述しました。
しかし、ソースコードとして何処かに記述しておかないと、ミスしたときの修正や、改良ができませんので、このプログラムのソースコードとして保存し、実行してみる事にします。
SET ECHO ON
BEGIN
DBMS_OUTPUT.PUT_LINE('HELLO WORLD2');
END;
/
これをSQLファイルとして、適当なディレクトリに保存します。
今回は、実行環境にoracleユーザーがいますので、そのホームディレクトリの直下に、plsqlというディレクトリを作成しました。
そこにLIST2-4.SQL の名前で上記の内容を保存します。
実行は、
SQL> START /home/oracle/plsql/LIST2-4.SQL
SQL> BEGIN
2 DBMS_OUTPUT.PUT_LINE('HELLO WORLD2');
3 END;
4 /
HELLO WORLD2
PL/SQLプロシージャが正常に完了しました。
SQL>
で正常に実行できました。
データを取得する
今回、使用しているのは、Oracleデータベースのサンプルスキーマ HRです。
なので、SELECTでデータが取得できます。
SELECT * FROM EMPLOYEES;
EMPLOYEE_ID FIRST_NAME LAST_NAME
----------- -------------------- -------------------------
EMAIL PHONE_NUMBER HIRE_DAT JOB_ID SALARY
------------------------- -------------------- -------- ---------- ----------
COMMISSION_PCT MANAGER_ID DEPARTMENT_ID
-------------- ---------- -------------
100 Steven King
SKING 515.123.4567 03-06-17 AD_PRES 24000
90
101 Neena Kochhar
NKOCHHAR 515.123.4568 05-09-21 AD_VP 17000
100 90
EMPLOYEE_ID FIRST_NAME LAST_NAME
----------- -------------------- -------------------------
EMAIL PHONE_NUMBER HIRE_DAT JOB_ID SALARY
------------------------- -------------------- -------- ---------- ----------
COMMISSION_PCT MANAGER_ID DEPARTMENT_ID
-------------- ---------- -------------
102 Lex De Haan
LDEHAAN 515.123.4569 01-01-13 AD_VP 17000
100 90
103 Alexander Hunold
AHUNOLD 590.423.4567 06-01-03 IT_PROG 9000
EMPLOYEE_ID FIRST_NAME LAST_NAME
----------- -------------------- -------------------------
~中略~
107行が選択されました。
しかし、PL/SQL上では、SELECTでデータを取得できません。
試しに、上記のSELECT文を発行してみます。
SET ECHO ON
BEGIN
SELECT * FROM EMPLOYEES;
END;
/
を5-1.SQLというファイルにして実行すると
SQL> START /home/oracle/plsql/5-1.SQL
SQL> SET ECHO ON
SQL> BEGIN
2 SELECT * FROM EMPLOYEES;
3 END;
4 /
SELECT * FROM EMPLOYEES;
*
行2でエラーが発生しました。:
ORA-06550: 行2、列4:
PLS-00428: INTO句はこのSELECT文に入ります。
SQL>
とエラーになります。
これはPL/SQL上ではSELECTは直接実行できず、SELECT INFO を使用するためです。
また、他のプログラムでもそうですが、実行した結果をどこにどのように戻すのかは必須の記述になりますが、これには記載されていません。
SELECT INFOを使用し、戻り値は変数に格納して、PUT_LINEで表記する事になります。
SET ECHO ON
DECLARE
v_department_id EMPLOYEES.DEPARTMENT_ID%TYPE;
v_first_name EMPLOYEES.FIRST_NAME%TYPE;
v_last_name EMPLOYEES.LAST_NAME%TYPE;
BEGIN
SELECT DEPARTMENT_ID,FIRST_NAME,LAST_NAME
INTO v_department_id,v_first_name,v_last_name
FROM EMPLOYEES
WHERE EMPLOYEE_ID =100;
DBMS_OUTPUT.PUT_LINE('ID:'||v_department_id);
DBMS_OUTPUT.PUT_LINE('NAME:'||v_first_name || ' ' ||v_last_name);
END;
/
これを、5-3.SQLというファイルにして実行すると
SQL> START /home/oracle/plsql/5-3.SQL
SQL> SET ECHO ON
SQL> DECLARE
2 v_department_id EMPLOYEES.DEPARTMENT_ID%TYPE;
3 v_first_name EMPLOYEES.FIRST_NAME%TYPE;
4 v_last_name EMPLOYEES.LAST_NAME%TYPE;
5 BEGIN
6 SELECT DEPARTMENT_ID,FIRST_NAME,LAST_NAME
7 INTO v_department_id,v_first_name,v_last_name
8 FROM EMPLOYEES
9 WHERE EMPLOYEE_ID =100;
10
11 DBMS_OUTPUT.PUT_LINE('ID:'||v_department_id);
12 DBMS_OUTPUT.PUT_LINE('NAME:'||v_first_name || ' ' ||v_last_name);
13 END;
14 /
ID:90
NAME:Steven King
PL/SQLプロシージャが正常に完了しました。
SQL>
SQLでの実行結果と比較すると
SQL> SELECT DEPARTMENT_ID,FIRST_NAME,LAST_NAME
2 FROM EMPLOYEES
3 WHERE EMPLOYEE_ID =100;
DEPARTMENT_ID FIRST_NAME LAST_NAME
------------- -------------------- -------------------------
90 Steven King
SQLの実行結果と合致しています。正常にデータが取得できています。
プロシージャーとして登録する
SQL処理をプログラムとして登録できるPL/SQLは、所定の処理を記述しておき、それを呼び出す事で実際の処理部分の考慮やプログラミングを短縮できるので便利です。
今回、当たった仕事というのも、プログラム部分は新しい言語に書換するリプレース案件なのですが、データベース処理に関しては基本的にストアドプロシージャーが用意されていて、それを呼び出すものでした。
結果、全くではないものの、SQLの記述は殆ど無いという形になっていました。
早速、簡単なPL/SQLをプロシージャーとして登録してみます。
CREATE OR REPLACE PROCEDURE MYPROC
IS
BEGIN
DBMS_OUTPUT.PUT_LINE('プロシージャーを実行');
END;
/
登録されたプロシージャーは、WindowsのA5からも確認できました。
データを出し入れするプロシージャー
SQLを実行するのですから、通常、パラメータを与え、結果を受け取る処理は必須になります。
PL/SQLの場合、IN指定で入力するパラメータに値を入れ、実行し、OUT指定の変数で結果を受け取ります。
データを取得する で使用したSELECT INTOを、プロシージャーにしてみましょう。
CREATE OR REPLACE PROCEDURE myout_param_proc(
p_param1 IN NUMBER DEFAULT 0
, p_returnid OUT NUMBER
, p_fullname OUT VARCHAR2
)
IS
v_department_id EMPLOYEES.DEPARTMENT_ID%TYPE;
v_first_name EMPLOYEES.FIRST_NAME%TYPE;
v_last_name EMPLOYEES.LAST_NAME%TYPE;
v_id NUMBER;
BEGIN
SELECT DEPARTMENT_ID,FIRST_NAME,LAST_NAME
INTO v_department_id,v_first_name,v_last_name
FROM EMPLOYEES
WHERE EMPLOYEE_ID =p_param1;
p_returnid := v_department_id;
p_fullname := v_first_name || ' ' ||v_last_name;
END;
/
これをOracleデータベースのサーバーのsqlplusで実行すると、myout_param_proc というストアドが登録されます。
WindowsパソコンのA5からも確認でき、入力パラメータのp_param1に100を入力すれば、90とSteven King が返ってきます。
後は目的にあわせ、SQLを組み立てていき、必要なパラメータと、取得する結果を列記すれば、プロシージャーを呼び出すだけで処理が完結します。
プロシージャーをVB.NETから呼び出す
駆け足ですが、作成したVB.NETから、上記で作成したストアドプロシージャーを呼び出してみます。
基本は以前の記事で各データベースへの接続を参考に、プロジェクトにODP.NETをインストールし、接続モジュールを用意します。
Imports Oracle.ManagedDataAccess.Client
Module Module1
Public oracleCon As New OracleConnection
Public oracleCmd As New OracleCommand
Public sqlCommand As New OracleCommand
Sub sql_st()
''データベースに接続
Dim Builder As OracleConnectionStringBuilder = New OracleConnectionStringBuilder()
' データベースに接続するために必要な情報をBuilderに与える
Builder.DataSource = "ORACLE19C"
Builder.UserID = "HR"
Builder.Password = "HR"
oracleCon.ConnectionString = Builder.ConnectionString
'oracleCon.ConnectionString = "DATA SOURCE=ORACLE19C;USER ID=HR;PASSWORD=HR"
oracleCon.Open()
End Sub
Sub sql_cl()
' データベースの切断
oracleCon.Close()
End Sub
End Module
Formには次のように記述しました。
Imports Oracle.ManagedDataAccess.Client
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Try
sql_st()
oracleCmd.Connection = oracleCon
'コマンドタイプをストアドプロシージャにする
oracleCmd.CommandType = CommandType.StoredProcedure
'実行するストアドプロシージャを指定
oracleCmd.CommandText = "myout_param_proc"
'ストアドプロシージャの引数に渡す値の設定
oracleCmd.Parameters.Add("p_param1", OracleDbType.Int32).Value = Integer.Parse(Me.TextBox1.Text)
'ストアドプロシージャのout用パラメータ作成
Dim outPara As New OracleParameter("p_returnid", OracleDbType.Int32)
outPara.Direction = ParameterDirection.Output
oracleCmd.Parameters.Add(outPara)
Dim outPara2 As New OracleParameter("p_fullname", OracleDbType.Varchar2, 256)
outPara2.Direction = ParameterDirection.Output
oracleCmd.Parameters.Add(outPara2)
'ストアドプロシージャの実行
oracleCmd.ExecuteNonQuery()
Me.TextBox2.Text = outPara.Value.ToString
Me.TextBox3.Text = outPara2.Value.ToString
MessageBox.Show("PROCEDURE3 正常終了 COUNT=" & outPara.Value.ToString(), "SUCCESS",
MessageBoxButtons.OK, MessageBoxIcon.Information)
sql_cl()
Catch OraEx As OracleException
'Oracle例外発生時
MessageBox.Show(OraEx.Message, "ORACLE ERROR",
MessageBoxButtons.OK, MessageBoxIcon.Stop)
sql_cl()
Catch ex As Exception
'一般例外発生時
MessageBox.Show(ex.Message, "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Stop)
sql_cl()
End Try
End Sub
End Class
パラメーターとして、上のテキストボックスから値を取り、ストアドプロシージャーに送り、戻った結果をテキストボックス2つに格納しています。
返り値のVarchar2, 256 のように長さの指定が必要だったり、少々複雑な感じはしますが、決まった形状なので問題は無さそうです。
よりプログラムらしい動作
PL/SQLはプログラム言語なので、IF文による条件分岐や、FOR ループなどの処理がありますので、条件をつけて処理を分岐したり繰り返す事で複雑な処理を実装する事も可能です。
例えば、INでパラメータを与え、それを元にいくつかのテーブルを検索してデータを収集し、最終的に得られたデータでテーブルを検索して最終データを得るというような行程を組む事もできます。
簡単な例として先出のデータを出し入れするプロシージャーに幾つか変数を追加して、条件分岐を設定してみます。
CREATE OR REPLACE PROCEDURE myout_param_proc(
p_param1 IN NUMBER DEFAULT 0
, p_type IN VARCHAR2
, p_date IN DATE
, p_returnid OUT NUMBER
, p_fullname OUT VARCHAR2
)
IS
v_department_id EMPLOYEES.DEPARTMENT_ID%TYPE;
v_first_name EMPLOYEES.FIRST_NAME%TYPE;
v_last_name EMPLOYEES.LAST_NAME%TYPE;
v_id NUMBER;
BEGIN
IF p_type IS NULL THEN
SELECT DEPARTMENT_ID,FIRST_NAME,LAST_NAME
INTO v_department_id,v_first_name,v_last_name
FROM EMPLOYEES
WHERE EMPLOYEE_ID = p_param1;
ELSE
SELECT DEPARTMENT_ID,FIRST_NAME,LAST_NAME
INTO v_department_id,v_first_name,v_last_name
FROM EMPLOYEES
WHERE HIRE_DATE = p_date;
END IF;
p_returnid := v_department_id;
p_fullname := v_first_name || ' ' ||v_last_name;
END;
/
改修点は、p_type p_dateという変数を追加しました。
そのp_type がNullかどうかを判定し、Nullだったときは、今までと同じ動作をし、Null以外は、p_dateを日付の条件として、実行するSQLが変わるようにしました。
WindowsのA5から確認すると、パラメータが増えているのが判ります。
早速、実行してみましょう。
今回のPL/SQLでは、p_typeがNullかどうかで判定されますので、NULLの状態のまま、100を与えると、
SELECT
DEPARTMENT_ID
, FIRST_NAME
, LAST_NAME
FROM
EMPLOYEES
WHERE
EMPLOYEE_ID = 100
---------
DEPARTMENT_ID FIRST_NAME LAST_NAME
90 Steven King
が実行されます。
一方、100の数値を指定せず、p_typeになにか文字列を入れ、日付を指定すると、
SELECT
DEPARTMENT_ID
, FIRST_NAME
, LAST_NAME
FROM
EMPLOYEES
WHERE
HIRE_DATE = TO_DATE('2008/03/24','YYYY/MM/DD')
------------
DEPARTMENT_ID FIRST_NAME LAST_NAME
80 Sundar Ande
SQLとして、こちらが実行されます。
今回はNullかそうでないかの比較ですが、パラメーターから与える文字列で条件分岐すれば、より複雑なSQLの実行とその結果出力が可能です。
プロシージャーをVB.NETから呼び出す2
それでは、この改造ストアドプロシージャーをVB.NETから呼び出してみましょう。
まず、フォームを改造して、テキストボックスを一つ増やし、チェックボックスを新設します。
チェックボックスにチェックを入れたら、新しい日付での検索。
チェックボックスを空欄のままだと、番号で検索する従来の方法で呼び出すため、次のようにします。
Private Sub CheckBox1_CheckedChanged(sender As Object, e As EventArgs) Handles CheckBox1.CheckedChanged
If CheckBox1.Checked = True Then
Me.TextBox1.Visible = False
Me.TextBox4.Visible = True
Else
Me.TextBox1.Visible = True
Me.TextBox4.Visible = False
End If
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Me.CheckBox1.Checked = False
Me.TextBox4.Visible = False
End Sub
チェックのオン/オフで入力枠の表示/非表示を切り換えます。
初期はチェックがはずれているようにします。
しかし、次のコードは実際にはエラーが発生します。
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Try
sql_st()
oracleCmd.Connection = oracleCon
'コマンドタイプをストアドプロシージャにする
oracleCmd.CommandType = CommandType.StoredProcedure
'実行するストアドプロシージャを指定
oracleCmd.CommandText = "myout_param_proc"
'ストアドプロシージャの引数に渡す値の設定
''チェックBOXで引き渡すパラメータを変更
If CheckBox1.Checked = True Then
oracleCmd.Parameters.Add("p_param1", OracleDbType.Int32).Value = DBNull.Value
oracleCmd.Parameters.Add("p_type", OracleDbType.Int32).Value = "A"
oracleCmd.Parameters.Add("p_date", OracleDbType.Date).Value = CDate(Me.TextBox4.Text)
Else
'ID値
oracleCmd.Parameters.Add("p_param1", OracleDbType.Int32).Value = Integer.Parse(Me.TextBox1.Text)
oracleCmd.Parameters.Add("p_type", OracleDbType.Int32).Value = DBNull.Value
oracleCmd.Parameters.Add("p_date", OracleDbType.Date).Value = DBNull.Value
End If
'ストアドプロシージャのout用パラメータ作成
Dim outPara As New OracleParameter("p_returnid", OracleDbType.Int32)
outPara.Direction = ParameterDirection.Output
oracleCmd.Parameters.Add(outPara)
Dim outPara2 As New OracleParameter("p_fullname", OracleDbType.Varchar2, 256)
outPara2.Direction = ParameterDirection.Output
oracleCmd.Parameters.Add(outPara2)
'ストアドプロシージャの実行
oracleCmd.ExecuteNonQuery()
Me.TextBox2.Text = outPara.Value.ToString
Me.TextBox3.Text = outPara2.Value.ToString
MessageBox.Show("PROCEDURE3 正常終了 COUNT=" & outPara.Value.ToString(), "SUCCESS",
MessageBoxButtons.OK, MessageBoxIcon.Information)
sql_cl()
Catch OraEx As OracleException
'Oracle例外発生時
MessageBox.Show(OraEx.Message, "ORACLE ERROR",
MessageBoxButtons.OK, MessageBoxIcon.Stop)
sql_cl()
Catch ex As Exception
'一般例外発生時
MessageBox.Show(ex.Message, "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Stop)
sql_cl()
End Try
End Sub
注意点という程でもないですが、データ型がかなりシビアです。
特にNullを代入するときは、通常、VB.NETで使用する DBNull.Value をそのまま代入しようとすると失敗します。
Nullをパラメータとして与える場合は、OracleParameterとしての変数をきちんと作成した上で代入する必要があります。
正しいコードは、次のようになります。
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Try
sql_st()
oracleCmd.Connection = oracleCon
'コマンドタイプをストアドプロシージャにする
oracleCmd.CommandType = CommandType.StoredProcedure
'実行するストアドプロシージャを指定
oracleCmd.CommandText = "myout_param_proc"
'ストアドプロシージャの引数に渡す値の設定
''チェックBOXで引き渡すパラメータを変更
If CheckBox1.Checked = True Then
Dim inPara1 As New OracleParameter("p_param1", OracleDbType.Int32)
inPara1.Direction = ParameterDirection.Input
inPara1.Value = DBNull.Value
oracleCmd.Parameters.Add(inPara1)
oracleCmd.Parameters.Add("p_type", OracleDbType.Varchar2).Value = "A"
oracleCmd.Parameters.Add("p_date", OracleDbType.Date).Value = CDate(Me.TextBox4.Text)
Else
'ID値
oracleCmd.Parameters.Add("p_param1", OracleDbType.Int32).Value = Integer.Parse(Me.TextBox1.Text)
Dim inPara1 As New OracleParameter("p_type", OracleDbType.Varchar2)
inPara1.Direction = ParameterDirection.Input
inPara1.Value = DBNull.Value
oracleCmd.Parameters.Add(inPara1)
Dim inPara2 As New OracleParameter("p_date", OracleDbType.Date)
inPara2.Direction = ParameterDirection.Input
inPara2.Value = DBNull.Value
oracleCmd.Parameters.Add(inPara2)
End If
'ストアドプロシージャのout用パラメータ作成
Dim outPara As New OracleParameter("p_returnid", OracleDbType.Int32)
outPara.Direction = ParameterDirection.Output
oracleCmd.Parameters.Add(outPara)
Dim outPara2 As New OracleParameter("p_fullname", OracleDbType.Varchar2, 256)
outPara2.Direction = ParameterDirection.Output
oracleCmd.Parameters.Add(outPara2)
'ストアドプロシージャの実行
oracleCmd.ExecuteNonQuery()
Me.TextBox2.Text = outPara.Value.ToString
Me.TextBox3.Text = outPara2.Value.ToString
MessageBox.Show("PROCEDURE3 正常終了 COUNT=" & outPara.Value.ToString(), "SUCCESS",
MessageBoxButtons.OK, MessageBoxIcon.Information)
sql_cl()
Catch OraEx As OracleException
'Oracle例外発生時
MessageBox.Show(OraEx.Message, "ORACLE ERROR",
MessageBoxButtons.OK, MessageBoxIcon.Stop)
sql_cl()
Catch ex As Exception
'一般例外発生時
MessageBox.Show(ex.Message, "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Stop)
sql_cl()
End Try
End Sub
チェックを入れず、数値を入れるとID検索になり、ストアドが実行され、結果が表示されます。
チェックを入れると、テキストボックスの日付を与え、日付検索の結果が表示されています。
まとめ
今回のお仕事はDB周りはストアドに任せるものでしたのでVBのユーザーインターフェイスを作り、上記のような方法でストアドに接続してデータを得るというものでした。
ストアドの方は、DB部門が作ったものなので中身は見たくらいですが、プログラム言語としてはかなりいろいろな事ができますので、データベース処理はPL/SQLに記述し、それを呼び出す事でいろいろと面白い事ができそうです。
参考書籍にも書かれていましたが、特にクライアント機台数が多い場合、サーバーとのやりとりが、ストアドプロシージャーにパラメータを送る→結果を受け取る だけで済むため、トラフィックを大幅に節約できそうです。
また、DBチームとUIチームのように開発を分担し、必要なSQL問い合わせをストアドプロシージャ化すれば、開発の工程圧縮もできそうですね。
今後もいろいろ使えそうなので、自身のスキルとしていきたいと思いました。