- PR -

C#からOracleのストアドの実行について

投稿者投稿内容
KT
会議室デビュー日: 2006/05/17
投稿数: 5
投稿日時: 2006-05-17 13:54
はじめまして。
C#からOracleのストアドの実行について分からないことがありますので教えてください。
ストアドの引数に配列型を宣言しているのですが、
C#からそのストアドを実行すると配列型の部分が「型が違います」となり実行できません。

C#で設定しているパラメータの型が誤っているのだと思います。
色々と調べたのですが分かりませんので教えてください。

ストアドは▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽
CREATE OR REPLACE PACKAGE PA_test AS

-- CURSOR Typeの宣言
TYPE csrCURSOR IS REF CURSOR;
-- 関数の定義
TYPE CHAR_13 IS TABLE OF CHAR(13) INDEX BY BINARY_INTEGER;

PROCEDURE SP_Test3(
anSTART IN CHAR_13, --入力件数
aiCOUNT out PLS_INTEGER);
END PA_test;
/

CREATE OR REPLACE PACKAGE BODY PA_test AS

PROCEDURE SP_Test3(
anSTART IN CHAR_13, --入力件数
aiCOUNT out PLS_INTEGER
)
IS
liCOUNT PLS_INTEGER;
BEGIN
liCOUNT := anSTART.count;
--戻り値を設定
aiCOUNT := liCOUNT;
END SP_Test3;
END PA_test;

C#は▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽
OracleConnection connection = new OracleConnection(connectionString);
connection.Open();
string[] strSTART = new string [2];
int c = 0;
OracleCommand oraCommand = new OracleCommand (
" BEGIN PA_test.SP_Test3( :anSTART,:aiCOUNT ); END; ", connection);

strSTART[0]= "2005121400038";
strSTART[1]= "2005121400039";

oraCommand.Parameters.Add("anSTART",OracleDbType.Char,strSTART,ParameterDirection.Input );
oraCommand.Parameters.Add("aiCOUNT",OracleDbType.Int32 ,c,ParameterDirection.Output );

oraCommand.ArrayBindCount = 2;

oraCommand.ExecuteNonQuery();

宜しくおねがいします。
むら
会議室デビュー日: 2006/04/11
投稿数: 11
お住まい・勤務地: さっぽろ
投稿日時: 2006-05-17 14:13
こんにちは。


OracleDbType.RefCursor
でいかがでしょうか。

http://www.atmarkit.co.jp/fdb/rensai/odpdotnet01/odpdotnet04.html
かるあ
ぬし
会議室デビュー日: 2003/11/16
投稿数: 1190
お住まい・勤務地: センガワ→ムサシノ
投稿日時: 2006-05-17 14:14
引用:

KTさんの書き込み (2006-05-17 13:54) より:

string[] strSTART = new string [2];
int c = 0;
OracleCommand oraCommand = new OracleCommand (
" BEGIN PA_test.SP_Test3( :anSTART,:aiCOUNT ); END; ", connection);

strSTART[0]= "2005121400038";
strSTART[1]= "2005121400039";

oraCommand.Parameters.Add("anSTART",OracleDbType.Char,strSTART,ParameterDirection.Input );
oraCommand.Parameters.Add("aiCOUNT",OracleDbType.Int32 ,c,ParameterDirection.Output );

oraCommand.ArrayBindCount = 2;


aiCOUNT の
CollectionType, ArrayBindSize, Size の設定が抜けているように思えます。
配列引数、それも文字列の場合は特にややこしいですよね

http://www.atmarkit.co.jp/fdb/rensai/odpdotnet03/odpdotnet03_3.html

# リンクを追加

[ メッセージ編集済み 編集者: かるあ 編集日時 2006-05-17 14:16 ]
KT
会議室デビュー日: 2006/05/17
投稿数: 5
投稿日時: 2006-05-17 19:24
「むら」さん、「かるあ」さん
ありがとうございます。

少し確認するのに時間がかかってしまいましたが、
配列型を定義したストアドを実行することができました。
本当にありがとうございます。

2点、確認しているときに疑問が発生しましたので教えていただけないでしょうか?

1つ目は、
配列型をOUTのパラメータに設定したとき
cmd.Parameters[0].Value で値を取得できると思ったのですが、取得できませんでした。Parameters[0]のデータタイプを取得していました。
Value 以外にも引数の値を受け取る方法ってあるのでしょうか?

2つ目は、
カーソルを使用する場合のSelectにdecode等 を使用しても実行できるのでしょうか?
ストアドで実行するとエラーが発生していました。回避策等ありましたら教えてください。

OPEN v_cursor FOR
SELECT A, B, C,decode(C,0,'親','子')
FROM D_TEST;

宜しくお願いします。
かるあ
ぬし
会議室デビュー日: 2003/11/16
投稿数: 1190
お住まい・勤務地: センガワ→ムサシノ
投稿日時: 2006-05-17 20:40
引用:

KTさんの書き込み (2006-05-17 19:24) より:

cmd.Parameters[0].Value で値を取得できると思ったのですが、取得できませんでした。Parameters[0]のデータタイプを取得していました。
Value 以外にも引数の値を受け取る方法ってあるのでしょうか?


どのようにキャストしているかわかりませんが
Value.toString() が呼び出されているんじゃないですか?

引用:

OPEN v_cursor FOR
SELECT A, B, C,decode(C,0,'親','子')
FROM D_TEST;


別名をつけて取ってください
KT
会議室デビュー日: 2006/05/17
投稿数: 5
投稿日時: 2006-05-18 16:53
「かるあ」さん返事ありがとうございます。

引用1:
--------------------------------------------------------------------------------
別名をつけて取ってください
--------------------------------------------------------------------------------
ご指摘の通り別名を設定したら問題なく取得できました。
ありがとうございます。

引用2:
--------------------------------------------------------------------------------
どのようにキャストしているかわかりませんが
Value.toString() が呼び出されているんじゃないですか?
--------------------------------------------------------------------------------
「かるあ」さんの指摘通りtoString()されていました。

配列のパラメータ.Valueをコマンドウィンドウで実行すると
{System.Array}
[0]: {Oracle.DataAccess.Types.OracleDecimal}
[1]: {Oracle.DataAccess.Types.OracleDecimal}
[2]: {Oracle.DataAccess.Types.OracleDecimal}
となるのに色々とキャストを試みたのですが、配列として認識してくれません。
クイックウォッチで確認すると
((System.Object)((配列のパラメータ.Value)))[0].Value に 取得したい値は入っていますが配列として認識してくれませんでした。

もしかしてC#からストアドを実行すると配列型の値は取得できないのでしょうか?
教えてください。

宜しくお願いします。
かるあ
ぬし
会議室デビュー日: 2003/11/16
投稿数: 1190
お住まい・勤務地: センガワ→ムサシノ
投稿日時: 2006-05-18 17:17
引用:

KTさんの書き込み (2006-05-18 16:53) より:

配列のパラメータ.Valueをコマンドウィンドウで実行すると
{System.Array}
[0]: {Oracle.DataAccess.Types.OracleDecimal}
[1]: {Oracle.DataAccess.Types.OracleDecimal}
[2]: {Oracle.DataAccess.Types.OracleDecimal}
となるのに色々とキャストを試みたのですが、配列として認識してくれません。
クイックウォッチで確認すると
((System.Object)((配列のパラメータ.Value)))[0].Value に 取得したい値は入っていますが配列として認識してくれませんでした。


out で配列を定義したことがないのでわかりませんが
色々なキャストというのはどんなキャストを試しましたか?
KT
会議室デビュー日: 2006/05/17
投稿数: 5
投稿日時: 2006-05-18 18:06
お世話になっています。
余り覚えていないのですがは、下の4パタンは試しました。
4:に関しては、キャストできませんでしたが・・・。

1:(System.Array)(パラメータ.Value)
2:((System.Object)((パラメータ.Value))
3:((System.Array)((System.Object)((パラメータ.Value))))
4:(Oracle.DataAccess.Types.OracleDecimal[])((System.Object)((パラメータ.Value))) 

C#を使いこなしていないのでキャストの仕方に問題があるのかもしれません。

とりあえずこんな感じです。

スキルアップ/キャリアアップ(JOB@IT)