サーバー側のカーソルを取得して使用する

  PL/SQL 側のコード





カーソルを外部に渡す為、パーケージ記述ができ無い場合は SYS_REFCURSOR を使用します
カーソルは、OUT で定義して、OPEN を行いますが、閉じません

  
PROCEDURE 引数テスト_CUR
(
	PM_01 IN VARCHAR2
	,PM_02 OUT SYS_REFCURSOR
)

/**********************************************************/
/* 変数の定義 */
/**********************************************************/
AS
	WK_VALUE	VARCHAR2(2000);
	TYPE カーソル型 IS REF CURSOR;
	検索cur カーソル型;

/**********************************************************/
/* 処理開始 */
/**********************************************************/
BEGIN
	DBMS_OUTPUT.PUT_LINE('デバッグ:開始');
	DBMS_OUTPUT.PUT_LINE('デバッグ:引数:'||PM_01);

	/**********************************************************/
	/* 動的 SELECT */
	/**********************************************************/
	WK_VALUE := 'SELECT * FROM 社員マスタ WHERE 社員コード >= :仮引数';
	OPEN 検索cur for WK_VALUE using PM_01;
	PM_02 := 検索cur;

	DBMS_OUTPUT.PUT_LINE('デバッグ:終了');

/**********************************************************/
/* 一番外側のブロックの例外処理 */
/**********************************************************/
EXCEPTION
	WHEN OTHERS THEN
		DBMS_OUTPUT.PUT_LINE('例外発生:'||SQLCODE||':'||SQLERRM);
END;
  



  VB.NET 側のコード



  
RecordSet = myCommand.ExecuteReader()

を以下のように変更する事も可能です

myCommand.ExecuteNonQuery()
RecordSet = CType(SERVER_CUR.Value, OracleDataReader)

※ これは、複数のカーソルを取得可能である事を示しています
  

  
Public myCon As New OracleConnection()
Public myCommand As New OracleCommand()
Dim Query As String = Nothing

' ******************************************************
' サーバー側のカーソルを取得して使用する
' ******************************************************
Private Sub 引数テストCURToolStripMenuItem_Click(ByVal sender As System.Object, _
 ByVal e As System.EventArgs) Handles 引数テストCURToolStripMenuItem.Click

	myCon.ConnectionString = _
	 "Server=night/xe;" + _
	 "User ID=ora01;" + _
	 "Password=ora01;"

	' *******************************************
	' 接続
	' *******************************************
	Try
		myCon.Open()
		myCommand.Connection = myCon
	Catch ex As Exception
		MessageBox.Show(ex.Message)
		Return
	End Try

	' *******************************************
	' DBMS_OUTPUT の結果を取得する為に使用可能にする
	' *******************************************
	Query = "BEGIN DBMS_OUTPUT.ENABLE(); END;"
	' コマンドをSQL用に変更
	myCommand.CommandType = CommandType.Text
	myCommand.CommandText = Query
	Try
		myCommand.ExecuteNonQuery()
	Catch ex As Exception
		myCon.Close()
		MessageBox.Show(ex.Message)
		Return
	End Try

	' *******************************************
	' プロシージャの実行
	' *******************************************
	' 実行タイプ
	myCommand.CommandType = CommandType.StoredProcedure
	' プロシージャ名
	myCommand.CommandText = "引数テスト_CUR"
	' パラメータクリア
	myCommand.Parameters.Clear()
	' 1つ目のパラメータ( IN なので簡単な記述方法 )
	myCommand.Parameters.Add("PM_01", OracleType.VarChar).Value = "0010"
	' 2つ目のパラメータ( OUT なので、パラメータオブジェクトを作成 )
	Dim SERVER_CUR As New OracleParameter("PM_02", OracleType.Cursor)
	SERVER_CUR.Direction = ParameterDirection.Output
	' 2つ目のパラメータを追加
	myCommand.Parameters.Add(SERVER_CUR)

	' カーソルを受け取る Reader
	Dim RecordSet As OracleDataReader = Nothing

	Try
		' 結果を受け取り、後で処理する
		RecordSet = myCommand.ExecuteReader()
	Catch ex As Exception
		myCon.Close()
		MessageBox.Show(ex.Message)
		Return
	End Try

	' *******************************************
	' DBMS_OUTPUT の結果を取得する
	' *******************************************
	myCommand.CommandType = CommandType.StoredProcedure
	myCommand.CommandText = "DBMS_OUTPUT.GET_LINE"
	myCommand.Parameters.Clear()

	Dim PARAM As OracleParameter = _
	  New OracleParameter("line", OracleType.VarChar)
	PARAM.Direction = ParameterDirection.Output
	PARAM.Size = 200
	myCommand.Parameters.Add(PARAM)
	Dim STATUS As OracleParameter = _
	 New OracleParameter("status", OracleType.Number)
	STATUS.Direction = ParameterDirection.Output
	myCommand.Parameters.Add(STATUS)

	Try
		myCommand.ExecuteNonQuery()
	Catch ex As Exception
		myCon.Close()
		MessageBox.Show(ex.Message)
		Return
	End Try

	' グリッドの列を作成
	Me.LboxGrid1.Reset()
	Me.LboxGrid1.AddColumn("LINE", "DBMS_OUTPUT.GET_LINEからのデバッグデータ")

	Do While STATUS.Value = 0

		Me.LboxGrid1.AddRow()
		Me.LboxGrid1.SetColumnText("LINE", PARAM.Value.ToString())

		Try
			myCommand.ExecuteNonQuery()
		Catch ex As Exception
			Exit Do
		End Try
	Loop

	' *******************************************
	' サーバーからのカーソルのデータを読み出す
	' *******************************************
	Dim line As String = ""
	Dim idx As Integer = 0
	Do While RecordSet.Read()

		Me.LboxGrid1.AddRow()
		idx = RecordSet.GetOrdinal("社員コード")
		line += RecordSet.GetValue(idx).ToString()
		idx = RecordSet.GetOrdinal("氏名")
		line += " | " + RecordSet.GetValue(idx).ToString()
		Me.LboxGrid1.SetColumnText("LINE", line)
		line = ""

	Loop

	' *******************************************
	' 終了処理
	' *******************************************
	RecordSet.Close()
	myCommand.Parameters.Clear()
	myCon.Close()

End Sub
  




  コロン( : ) を使った場合の引数の処理

コロンを使った方法でも結果は同じなので、こちらのほうが何を実行しようとしているが解り易いですし、
汎用性があります。

  
' *******************************************
' プロシージャの実行
' *******************************************
' 実行タイプ
myCommand.CommandType = CommandType.Text
' プロシージャ名
myCommand.CommandText = "BEGIN 引数テスト_CUR(:PM_01,:PM_02); END;"
' パラメータクリア
myCommand.Parameters.Clear()
' 1つ目のパラメータ( IN なので簡単な記述方法 )
myCommand.Parameters.Add("PM_01", OracleType.VarChar).Value = "0010"
' 2つ目のパラメータ( OUT なので、パラメータオブジェクトを作成 )
Dim SERVER_CUR As New OracleParameter("PM_02", OracleType.Cursor)
SERVER_CUR.Direction = ParameterDirection.Output
' 2つ目のパラメータを追加
myCommand.Parameters.Add(SERVER_CUR)

' カーソルを受け取る Reader
Dim RecordSet As OracleDataReader = Nothing

Try
	' 結果を受け取り、後で処理する
	RecordSet = myCommand.ExecuteReader()
Catch ex As Exception
	myCon.Close()
	MessageBox.Show(ex.Message)
	Return
End Try
  










  infoboard   管理者用   
このエントリーをはてなブックマークに追加





フリーフォントWEBサービス
SQLの窓WEBサービス

SQLの窓フリーソフト

素材

一般WEBツールリンク

SQLの窓

フリーソフト

JSライブラリ