C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

ログ内検索
  • キーワードを複数指定する場合は 半角スペース で区切ってください。
  • 検索条件は、(AND)=[A かつ B] (OR)=[A または B] となっています。
  • [返信]をクリックすると返信ページへ移動します。
キーワード/ 検索条件 /
検索範囲/ 強調表示/ ON (自動リンクOFF)
結果表示件数/ 記事No検索/ ON
大文字と小文字を区別する

全過去ログを検索

<< 0 >>
■100051  Oracle Package呼出時エラー PLS-00306
□投稿者/ AS702 -(2022/06/30(Thu) 19:15:50)

    分類:[C#] 

    Oracle Package呼出時エラー PLS-00306

    お世話になっております。
    C#よりOracleのPackageを呼び出すコーディングを行っておりますが、以下のエラーとなりデータの取得ができませんでした。
    どのようにしたら、データが取得できるかご教授願います。


    **************エラー内容Start**************
    ORA-06550: 行1、列7:
    PLS-00306: '検索'の呼出しで、引数の数または型が正しくありません。
    ORA-06550: 行1、列7:
    PLS-00306: '検索'の呼出しで、引数の数または型が正しくありません。
    ORA-06550: 行1、列7:
    PL/SQL: Statement ignored
    **************エラー内容End**************

    **************OraclePackage定義Start**************
    CREATE OR REPLACE PACKAGE P_顧客DB AS
    type 入力情報 is table of VARCHAR2(60) index by BINARY_INTEGER;
    type 出力情報 is table of VARCHAR2(60) index by BINARY_INTEGER;
    PROCEDURE 検索( In_更新有無 IN NUMBER,
    In_入力項目 IN 入力情報,    ← 本項目に店番(1)、顧客番号(123456)をセットして、該当レコードを取得します。
    Out_出力項目 OUT 出力情報 ); ← 本項目にselect文で取得したデータが入ります。(配列項目数:160個)
    END P_顧客DB;
    /
    **************OraclePackage定義End**************

    **************C#コーディングStart**************
    DataSet dSet = new DataSet();

    //データベース接続を開く
    OracleConnection conn = new OracleConnection(P.Default.conn_string);
    conn.Open();

    string [] p_In_入力項目 = new string[2];
    string [] p_In_出力項目 = new string[160];
    OracleCommand cmd = new OracleCommand();

    cmd.Connection = conn;
    cmd.BindByName = true;

    p_In_入力項目[0] = "1";
    p_In_入力項目[1] = "123456";

    cmd.Parameters.Add("O_顧客検索", OracleDbType.Varchar2, 60, p_In_出力項目, ParameterDirection.ReturnValue);
    cmd.Parameters.Add("int_更新有無", OracleDbType.Decimal, 0, ParameterDirection.Input);
    cmd.Parameters.Add("I_顧客検索", OracleDbType.Varchar2, 60, p_In_入力項目, ParameterDirection.Input);
    cmd.CommandText = "Begin P_顧客DB.検索(:int_更新有無,:I_顧客検索,:O_顧客検索);
    END;";

    cmd.ExecuteNonQuery(); ←ここでエラー発生

    //データの取得方法もご教授願いたいです。

    return dSet;
    **************C#コーディングEnd**************

    よろしくお願いいたします。
親記事 /過去ログ174より / 関連記事表示
削除チェック/

■100052  Re[1]: Oracle Package呼出時エラー PLS-00306
□投稿者/ KOZ -(2022/06/30(Thu) 19:33:26)
    2022/06/30(Thu) 19:49:23 編集(投稿者)

    No100051 (AS702 さん) に返信

    連想配列を使うには、OracleParameter の CollectionType プロパティを OracleCollectionType.PLSQLAssociativeArray にする必要があります。
    また、配列サイズを OracleParameter.Size にセットします。

    「PL/SQL連想配列の使用」
    https://www.oracle.com/jp/database/technologies/oramag/o17odp.html

    配列を受け取るときは ArrayBindSize を設定する必要があったと思います。
    cmd.Parameters("O_顧客検索").ArrayBindSize = Enumerable.Repeat<int>(60, 160).ToArray();
記事No.100051 のレス /過去ログ174より / 関連記事表示
削除チェック/

■100053  Re[2]: Oracle Package呼出時エラー PLS-00306
□投稿者/ KOZ -(2022/07/01(Fri) 00:30:47)
    No100052 (KOZ) に返信

    SELECT した結果を取得するなら、こういう方法もあります。

    「Oracleでパイプライン表関数を利用して表データを返却する」
    https://knkryo.blogspot.com/2013/12/oracle_24.html

    こうして作成した PACKAGE は

    SELECT * FROM TABLE(PKG_DATE_TABLE_UTIL.GET_YM_TABLE(202205, 202206))

    のように使用できます。
記事No.100051 のレス /過去ログ174より / 関連記事表示
削除チェック/

■100115  Re[2]: Oracle Package呼出時エラー PLS-00306
□投稿者/ AS702 -(2022/07/04(Mon) 17:32:07)
    2022/07/04(Mon) 17:37:42 編集(投稿者)
    No100052 (KOZ さん) に返信
    > 2022/06/30(Thu) 19:49:23 編集(投稿者)
    >
    > ■No100051 (AS702 さん) に返信
    >
    > 連想配列を使うには、OracleParameter の CollectionType プロパティを OracleCollectionType.PLSQLAssociativeArray にする必要があります。
    > また、配列サイズを OracleParameter.Size にセットします。
    >
    > 「PL/SQL連想配列の使用」
    > https://www.oracle.com/jp/database/technologies/oramag/o17odp.html
    >
    > 配列を受け取るときは ArrayBindSize を設定する必要があったと思います。
    > cmd.Parameters("O_顧客検索").ArrayBindSize = Enumerable.Repeat<int>(60, 160).ToArray();

    お忙しい中、ご回答ありがとうございます。
    以下のように修正してみました。
    そこで、3つ質問させてください。

    OracleConnection conn = new OracleConnection(P.Default.conn_string);
    conn.Open();

    OracleCommand cmd = conn.CreateCommand();
    cmd.CommandText = "Begin P_顧客DB.検索(:int_更新有無,:I_顧客検索,:O_顧客検索);END;";
    cmd.CommandType = CommandType.Text;

    OracleParameter p_更新有無 = new OracleParameter();
    OracleParameter p_In_入力項目 = new OracleParameter();
    OracleParameter p_In_出力項目 = new OracleParameter();

    p_更新有無.OracleDbType = OracleDbType.Decimal;
    p_In_入力項目.OracleDbType = OracleDbType.Varchar2;
    p_In_出力項目.OracleDbType = OracleDbType.Varchar2;

    p_In_入力項目.CollectionType = OracleCollectionType.PLSQLAssociativeArray;
    p_In_出力項目.CollectionType = OracleCollectionType.PLSQLAssociativeArray;

    p_In_入力項目.Value = new string[2] {"1", "123456"};
    p_更新有無.Value = 0;

    p_In_入力項目.Size = 2;
    p_In_出力項目.Size = 160;

    cmd.Parameter.Add("int_更新有無", p_更新有無.Value);
    cmd.Parameter.Add("I_顧客検索", p_In_入力項目.Value); @
    cmd.Parameter.Add("O_顧客検索", p_In_出力項目.Value);

    cmd.ExecuteNonQuery();

    質問1
     上記@の部分でNullReferenceExceptionエラーとなってしまいます。
     配列の値の入れ方が間違っているのでしょうか。

    質問2
     「ParameterDirection.ReturnValue」のような指定がどこにも見受けられないのですが、どこで行うのでしょうか。

    質問3
    ご指摘いただきました下記コーディングを入れたところ、コンパイルエラーとなりました。
    「cmd.Parameters("O_顧客検索").ArrayBindSize = Enumerable.Repeat<int>(60, 160).ToArray();」
    エラー内容「実行不可能なメンバー'Oracle.DataAccess.Client.OracleCommand.Parameters'をメソッドのように使用することはできません。」

    重ね重ね申し訳ございませんが、よろしくお願いいたします。
記事No.100051 のレス /過去ログ174より / 関連記事表示
削除チェック/

■100116  Re[3]: Oracle Package呼出時エラー PLS-00306
□投稿者/ KOZ -(2022/07/04(Mon) 18:44:41)
    No100115 (AS702 さん) に返信
    > 質問1
    >  上記@の部分でNullReferenceExceptionエラーとなってしまいます。
    >  配列の値の入れ方が間違っているのでしょうか。

    これは新しい OracleParameter を追加しようとしています。

    > cmd.Parameter.Add("int_更新有無", p_更新有無.Value);
    > cmd.Parameter.Add("I_顧客検索", p_In_入力項目.Value); @
    > cmd.Parameter.Add("O_顧客検索", p_In_出力項目.Value);

    cmd.Parameter.Add(p_更新有無);
    cmd.Parameter.Add(p_In_入力項目);
    cmd.Parameter.Add(p_In_出力項目);

    としてください。

    > 質問2
    >  「ParameterDirection.ReturnValue」のような指定がどこにも見受けられないのですが、どこで行うのでしょうか。

    Direction プロパティに設定します。
    p_更新有無.Direction = ParameterDirection.Input;
    p_In_入力項目.Direction = ParameterDirection.Input;
    p_In_出力項目.Direction = ParameterDirection.Output;

    ParameterDirection.ReturnValue は、CommandType = StoredProcedure の場合にストアドファンクションの戻り値として使います。

    > 質問3
    > ご指摘いただきました下記コーディングを入れたところ、コンパイルエラーとなりました。
    > 「cmd.Parameters("O_顧客検索").ArrayBindSize = Enumerable.Repeat<int>(60, 160).ToArray();」
    > エラー内容「実行不可能なメンバー'Oracle.DataAccess.Client.OracleCommand.Parameters'をメソッドのように使用することはできません。」

    すみmせん、cmd.Parameters["O_顧客検索"] の間違いです。
記事No.100051 のレス /過去ログ174より / 関連記事表示
削除チェック/

■100117  Re[3]: Oracle Package呼出時エラー PLS-00306
□投稿者/ KOZ -(2022/07/04(Mon) 18:57:02)
    No100115 (AS702 さん) に返信
    
    見直してみると、ParameterName の設定を忘れていますね。
    コンストラクタで複数のプロパティを指定しましょう、
    
    OracleParameter p_更新有無 = new OracleParameter("int_更新有無", OracleDbType.Decimal, ParameterDirection.Input);
    OracleParameter p_In_入力項目 = new OracleParameter("I_顧客検索", OracleDbType.Varchar2, ParameterDirection.Input);
    OracleParameter p_In_出力項目 =  = new OracleParameter("O_顧客検索", OracleDbType.Varchar2, ParameterDirection.Output);
    
記事No.100051 のレス /過去ログ174より / 関連記事表示
削除チェック/

■100118  Re[4]: Oracle Package呼出時エラー PLS-00306
□投稿者/ AS702 -(2022/07/04(Mon) 19:17:14)
    2022/07/04(Mon) 19:23:22 編集(投稿者)
    2022/07/04(Mon) 19:22:52 編集(投稿者)

    No100117 (KOZ さん) に返信
    > ■No100115 (AS702 さん) に返信
    >
    > 見直してみると、ParameterName の設定を忘れていますね。
    > コンストラクタで複数のプロパティを指定しましょう、
    >
    > OracleParameter p_更新有無 = new OracleParameter("int_更新有無", OracleDbType.Decimal, ParameterDirection.Input);
    > OracleParameter p_In_入力項目 = new OracleParameter("I_顧客検索", OracleDbType.Varchar2, ParameterDirection.Input);
    > OracleParameter p_In_出力項目 = = new OracleParameter("O_顧客検索", OracleDbType.Varchar2, ParameterDirection.Output);
    >

    ありがとうございます。
    おかげさまでエラーが消えました。
    アドバイスいただいた通り、修正したところ「p_In_出力項目」のValueの中に160個の値が入ったことを確認しました。

    簡単なことで申し訳ないのですが、p_In_出力項目の配列[1]に格納されている値をstring型の変数にいれる方法もご教授いただけないでしょうか。

    string test = p_In_出力項目.Value[0].ToString();
    など色々試してみましたが、コンパイルエラーとなってしまいます。
記事No.100051 のレス /過去ログ174より / 関連記事表示
削除チェック/

■100119  Re[5]: Oracle Package呼出時エラー PLS-00306
□投稿者/ KOZ -(2022/07/04(Mon) 19:25:59)
    No100118 (AS702 さん) に返信
    > 簡単なことで申し訳ないのですが、p_In_出力項目の配列[1]に格納されている値をstring型の変数にいれる方法もご教授いただけないでしょうか。

    OracleString[] になっているので、各要素を OracleString にキャストして Value プロパティを参照してください。
記事No.100051 のレス /過去ログ174より / 関連記事表示
削除チェック/

■100120  Re[6]: Oracle Package呼出時エラー PLS-00306
□投稿者/ AS702 -(2022/07/04(Mon) 20:12:54)
    No100119 (KOZ さん) に返信
    > ■No100118 (AS702 さん) に返信
    >>簡単なことで申し訳ないのですが、p_In_出力項目の配列[1]に格納されている値をstring型の変数にいれる方法もご教授いただけないでしょうか。
    >
    > OracleString[] になっているので、各要素を OracleString にキャストして Value プロパティを参照してください。
    >

    ご指摘の修正を行うことで、目指していたことが実現できました。
    本当にありがとうございました。

    修正したC#コーディングを記載しておきます。


    OracleConnection conn = new OracleConnection(P.Default.conn_string);
    conn.Open();

    OracleCommand cmd = conn.CreateCommand();
    cmd.CommandText = "Begin P_顧客DB.検索(:int_更新有無,:I_顧客検索,:O_顧客検索);END;";
    cmd.CommandType = CommandType.Text;

    OracleParameter p_更新有無 = new OracleParameter("int_更新有無", OracleDbType.Decimal, ParameterDirection.Input);
    OracleParameter p_In_入力項目 = new OracleParameter("I_顧客検索", OracleDbType.Varchar2, ParameterDirection.Input);
    OracleParameter p_In_出力項目 = = new OracleParameter("O_顧客検索", OracleDbType.Varchar2, ParameterDirection.Output);

    p_In_入力項目.CollectionType = OracleCollectionType.PLSQLAssociativeArray;
    p_In_出力項目.CollectionType = OracleCollectionType.PLSQLAssociativeArray;

    p_In_入力項目.Value = new string[2] {"1", "123456"}; //店番、顧客番号
    p_更新有無.Value = 0;

    p_In_入力項目.Size = 2;
    p_In_出力項目.Size = 160;

    p_In_出力項目.ArrayBindSize = Enumerable.Repeat<int>(60, 160).ToArray();

    cmd.Parameter.Add(p_更新有無);
    cmd.Parameter.Add(p_In_入力項目);
    cmd.Parameter.Add(p_In_出力項目);

    cmd.ExecuteNonQuery();

    OracleString[] OraStr = (OracleString[])(p_In_出力項目.Value);
    string[] arr = OraStr.Select(os => os.IsNull ? null : os.Value).ToArray();

    string val = arr[1].ToString();
    ⇒valに2個目の値がセットされた。
記事No.100051 のレス / END /過去ログ174より / 関連記事表示
削除チェック/

■100055  Re[1]: Oracle Package呼出時エラー PLS-00306
□投稿者/ radian -(2022/07/01(Fri) 08:58:19)
記事No.100051 のレス /過去ログ174より / 関連記事表示
削除チェック/

■100056  Re[2]: Oracle Package呼出時エラー PLS-00306
□投稿者/ KOZ -(2022/07/01(Fri) 09:32:41)
    No100055 (radian さん) に返信
    > ストアドの場合、
    > OracleCommand.CommandText=プロシージャ名
    > OracleCommand.CommandType=CommandType.StoredProcedure
    > みたいな感じだった気が。
    >
    > http://hiros-dot.net/VBNET2005/Other/ODPStored/ODPStored03.htm

    たしかにそれでもいけますが、このような "BEGIN プロシジャ名(:引数); END;" の形でもオッケーです。




記事No.100051 のレス /過去ログ174より / 関連記事表示
削除チェック/

■100058  Re[3]: Oracle Package呼出時エラー PLS-00306
□投稿者/ radian -(2022/07/01(Fri) 10:15:13)
    No100056 (KOZ さん) に返信
    > ■No100055 (radian さん) に返信
    >>ストアドの場合、
    >>OracleCommand.CommandText=プロシージャ名
    >>OracleCommand.CommandType=CommandType.StoredProcedure
    >>みたいな感じだった気が。
    >>
    >>http://hiros-dot.net/VBNET2005/Other/ODPStored/ODPStored03.htm
    >
    > たしかにそれでもいけますが、このような "BEGIN プロシジャ名(:引数); END;" の形でもオッケーです。

    なるほど、それは知りませんでした。
記事No.100051 のレス /過去ログ174より / 関連記事表示
削除チェック/

■100088  Re[3]: Oracle Package呼出時エラー PLS-00306
□投稿者/ KOZ -(2022/07/02(Sat) 08:44:40)
    2022/07/04(Mon) 03:42:33 編集(投稿者)

    No100056 (KOZ) に返信
    自分のメモ代わりに書いておきます。
    ストアドを呼ぶ際、引数の指定の仕方が2種類あります。

    「位置表記法と名前表記法」
    https://www.shift-the-oracle.com/plsql/positional-named-notation.html

    (1) CommandType = Text の場合

    位置表記法が使われ、CommandText に設定された SQL をそのままサーバーに送ります。

    BGEIN HOGE(:FOO, :BAR); END;

    (2) CommandType = StoredProcedure の場合

    OracleParameter.ParameterName が、引数の変数名として使われ、

    BEGIN HOGE(FOO=>:v0, BAR=>:v1); END;

    のように名前表記法を使った SQL を組み立ててサーバーに送ります。
    なので、ParameterName とストアドの引数名が一致している必要があります。
記事No.100051 のレス /過去ログ174より / 関連記事表示
削除チェック/



<< 0 >>

パスワード/

- Child Tree -