- - PR -
ODP.NETでIN引数に配列を持つストアドファンクションのパラメータセットについて
1
投稿者 | 投稿内容 |
---|---|
|
投稿日時: 2008-02-14 20:12
お世話になります。
既に既出のスレッドがあることを確認した上での質問なのですが OracleDBにIN引数として配列を持つストアドファンクションを作成の上、 VisualC#.NET+ODP.NETでファンクション呼び出しを行おうとしているのですが 配列引数の設定方法がまったくわかりません。oo4oではAddTableなるものが あることは存じているのですが・・・ 環境ですが、 OracleClient 9.2.0.1(但しPSR9.2.0.4のパッチ当て済み) ODP.NET 9.2.0.4 です。 下記にストアドファンクションの定義部とパッケージ部をそれぞれ載せます。 -------------- 定義部 CREATE OR REPLACE PACKAGE TEST.PKG_TEST AS TYPE value_table is table of number index by pls_integer; TYPE str_table is table of varchar2(10) index by pls_integer; FUNCTION F1( vals in value_table ) RETURN number; FUNCTION F2( strs in str_table ) RETURN number; END PKG_TEST; / ------------------------- パッケージ部 CREATE OR REPLACE PACKAGE BODY TEST.PKG_TEST AS FUNCTION F1 ( vals in value_table ) RETURN number IS BEGIN for i in vals.first..vals.last loop INSERT INTO TEMP(A, WRITE_TIME) values ( vals(i), sysdate); end loop; commit; return 0; END F1; OTNのサイトのマニュアルは既に閲覧済みです。 http://otndnld.oracle.co.jp/tech/windows/odpnet/howto/04_arraybind/content.html ここのサンプルを参考にコードを組んでみたのですが ストアドファンクションの例ではなく、動作しませんでした。 また、別な例として下記URLの記事を参考にしてコードを組んでみたのですが やはり動きませんでした。 http://otndnld.oracle.co.jp/document/products/oracle10g/102/windows/B31247-01/featOraCommand.htm#BABBDHBB http://www.atmarkit.co.jp/fdb/rensai/odpdotnet03/odpdotnet03_3.html いずれもストアドプロシージャを対象としていて ストアドファンクションの例ではありませんでした。 ODP.NETでストアドファンクションに配列パラメータを 渡す方法について、どなたかご教授ください。 作業が全然進まず、大変困っております。 どうぞよろしくお願いいたします。 |
|
投稿日時: 2008-02-17 21:11
もうしばらく Oracle に触っていないので間違えているかも知れないけれど、
プロシージャだろうが、ファンクションだろうが同じ方法でできたと思いますよ。 今はどういった状況ですか? エラーが出ている?出ているとしたらどんなエラー? まずはサンプルと同じ構成で正常にストアドプロシージャを呼ぶことができるか試してください。(サンプルと全く同じテーブルを作って呼んでみる) ストアドプロシージャとファンクションの違いって.NET側からは戻り値のパラメータを積むか積まないかの違いぐらいな気がする。 _________________ かるあ のメモ と スニペット |
|
投稿日時: 2008-02-17 21:44
ありゃ、RSSを眺めてたらこっちにもあったのね。
とりあえずリンクしとくか http://otn.oracle.co.jp/forum/thread.jspa?messageID=35022954&tstart=0#35022954 _________________ かるあ のメモ と スニペット |
|
投稿日時: 2008-02-18 19:38
かるあさん、レスポンスありがとうございます。
ストアドだけ載せたのでは判りにくいかなと思いましたので、C#側のコードも載せます。 --------------------------------- C#のコード using System; using System.Drawing; using System.Collections; using System.ComponentModel; using System.Windows.Forms; using System.Data; using Oracle.DataAccess.Client; namespace SFTest { /// <summary> /// Form1 の概要の説明です。 /// </summary> public class Form1 : System.Windows.Forms.Form { /// <summary> /// アプリケーションのメイン エントリ ポイントです。 /// </summary> [STAThread] static void Main() { Application.Run(new Form1()); } private OracleConnection dbConnect; private void Form1_Load(object sender, System.EventArgs e) { try { String connString = "Data Source=XXXXX;User ID=XXXXX;password=XXXXX;"; dbConnect = new OracleConnection(connString); if (dbConnect != null) { lblConnStatus.Text = "connect success!!"; // lblConnInfo.Text = "Connected to Oracle" + dbConnect.ServerVersion; } dbConnect.Open(); } catch (Exception econnect) { MessageBox.Show(econnect.Message); } } private void button1_Click(object sender, System.EventArgs e) { try { OracleCommand cmd = new OracleCommand( "PKG_TEST.F1", dbConnect); OracleParameter Param1 = cmd.Parameters.Add("1", OracleDbType.Int32); Param1.Direction = ParameterDirection.Input; Param1.CollectionType = OracleCollectionType.PLSQLAssociativeArray; Param1.Value = new int[3] {10, 20, 30}; Param1.Size = 3; Param1.ArrayBindSize = new int[3] {2, 2, 2}; Param1.ArrayBindStatus = new OracleParameterStatus[3] { OracleParameterStatus.Success, OracleParameterStatus.Success, OracleParameterStatus.Success}; cmd.ExecuteNonQuery(); } catch (Exception ecmdbutton1click) { MessageBox.Show(ecmdbutton1click.Message); } } } } ちなみに出ているエラーは ORA-00900:invalid SQL statement です。 SQL文がおかしいということは理解できるのですが、どこがどうおかしいのか 見当がつきません。 かるあさんの仰るとおり、サンプルと同じ構成でプロシージャが呼べるかどうか 試してみることにします。 |
|
投稿日時: 2008-02-18 23:36
環境がないので試していないですが、ストアドの場合
cmd.CommandType = CommandType.StoredProcedure が必要だったような気が。。。 |
|
投稿日時: 2008-03-25 11:49
レスが遅くなりましてすみません。自己解決しました。
以下のコードにて、動作を確認できました。 [pre] [STAThread] static void Main() { Application.Run(new Form1()); } private void btnExe_Click(object sender, System.EventArgs e) { // ORACLEコネクションの生成とコネクションのオープン OracleConnection conn = new OracleConnection(); conn.ConnectionString = "User Id=" + tbxUserID.Text + ";Password=" + tbxPassword.Text + ";Data Source=" + tbxSID.Text; conn.Open(); // ORACLEコマンドの生成 OracleCommand cmd = new OracleCommand(tbxFuncName.Text, conn); cmd.CommandType = CommandType.StoredProcedure; // パラメータのバインド OracleParameter ret = cmd.Parameters.Add("ret", OracleDbType.Int32); ret.Direction = ParameterDirection.ReturnValue; OracleParameter param = new OracleParameter(); param.OracleDbType = OracleDbType.Int32; OracleParameter param = new OracleParameter("vals", OracleDbType.Int32); param.Direction = ParameterDirection.Input; param.CollectionType = OracleCollectionType.PLSQLAssociativeArray; string delimStr = ","; char [] delimiter = delimStr.ToCharArray(); int [] num = null; string [] values = null; values = tbxParam1.Text.Split(delimiter,10); num = new int[values.Length]; for (int i = 0 ; i < values.Length ; i++) { num[i] = Int32.Parse(values[i]); } param.Size = values.Length; param.Value = num; cmd.Parameters.Add(param); // コマンドの実行 cmd.ExecuteNonQuery(); // 戻り値の表示 tbxRetValue.Text = ret.Value.ToString(); // ORACLEコネクションのクローズとディスポーズ conn.Close(); conn.Dispose(); } [pre] ご指摘いただいた皆様、どうもありがとうございました。 |
1