私はC#アプリケーションで作業しており、SQL文をSQL ServerからOracleに変換しています。私は値がメインテーブルと関連テーブルのいくつかのレコードに挿入されている1つのブロックを持っています。メインテーブルに重複レコードが存在するかどうかを確認し、C#ページにフラグ値を返します。そうでない場合はレコードを挿入し、メインテーブルのPKを取得して関連テーブルへの挿入に使用します。これまでのところ、ブロック内のOracleから値を返すための最良の方法は、InputOutputパラメータを使用することでした。 (ステートメントのどこにでもBEGIN/ENDブロックがあれば、INTOなしでSELECTすることはできません)Oracleブロック内のバインド変数(C#出力パラメータ)にリテラルを割り当てます。
SQL Serverでは、レコードを返さないSELECTステートメントから変数をロードしようとすると、変わらない。 Oracleでは、これを処理するためにNO_DATA_FOUND例外を設定する必要があることがわかりました。復帰フラグを設定する例外が必要です。 「ORA-06502:PL/SQL:数値エラーまたは値エラー」が表示されます。
BEGIN
SELECT ID INTO :REPORTID FROM Report WHERE ExtractDt=:EXTRACTDT
AND REGION=:RGN;
EXCEPTION WHEN NO_DATA_FOUND THEN
SELECT -1 INTO :REPORTID FROM DUAL;
END;
これは私が来た最も近いものです。 SELECT -1 ...行でエラーが発生します。
REPORTIDはNUMBER型のパラメータとして渡され、InputOutputの方向に渡されます。 EXTRACTDTは有効な値を持つ日付で、RGNはvarchar(2)文字列です。両方の入力パラメータ。
EDIT:ブロックは、C#からOracleに送られているかのサンプル:
OracleCommand psCmd = new OracleCommand();
psCmd.Connection = Conn; //Previously defined, valid & opened
psCmd.CommandType = CommandType.Text;
psCmd.CommandText = "{SQL STRING CONTAINING BLOCK, AS ABOVE}";
psCmd.Parameters.Add(new OracleParameter("REPORTID", OracleType.Number, 10) { Direction = ParameterDirection.InputOutput, Value = DBNull.Value });
psCmd.Parameters.Add(new OracleParameter("EXTRACTDT", OracleType.DateTime) { Value = dtExtract }); //C# DateTime with valid date
psCmd.Parameters.Add(new OracleParameter("RGN", OracleType.VarChar, 2) { Value = sRegion }); //C# String, 2 characters
psCmd.ExecuteNonQuery();
Int32 iID = (Int32)psCmd.Parameters["REPORTID"].Value;
//Cleanup, etc.
これは大きなブロックの単純化された部分です。完全なステートメントは戻り値をテストし、重複が見つからない場合は挿入し、フラグまたはIDをC#ページに返します。 – BlueKnot
REPORTIDの方向はInputOutputです(私はあなたのC#コードを参照していると思います)。 REPORTIDはどのようにPL/SQLコードで定義されていますか?これがプロシージャーの場合は、INまたはIN OUTと定義されていますか? 1つのコードスニペットに基づいて明確ではありません – tbone
@tboneあらかじめ定義された手順ではありません。ブロックはSQL文(C#文字列)として作成され、parametercollectionとともにOracleCommandオブジェクトに渡されます。 (文字列は、関連するテーブルのエントリ数[スニペットには表示されていません]が可変なので動的に作成されます)。 SQL Serverのバージョンでは、ブロックの先頭にDECLAREがありました。しかし、オラクルは私に 'Not all paramters bound'というエラーを出し、それを削除して代わりにパラメータ・コレクションの一部として渡す必要がありました。 – BlueKnot