0

OK、リストに保存するためにカーソル/結果セットをループしている問題を解決する方法を誰も知らないようです。だから、まず第一に:

この方法で SQL パラメータを OracleCommand オブジェクトに追加します (正常に動作します)。

cmd.Parameters.Add("ABCID", _ABCID);
cmd.Parameters["ABCID"].Direction = ParameterDirection.Input;
cmd.Parameters["ABCID"].DbType = DbType.String;

IOW、パラメーターを追加するときに、SQL のパラメーター化された部分の名前 (上記の「ABCID」) とそれに値を渡します (_ABCID は、割り当てられた変数です。たとえば、「42」とします)。

ただし、カーソル (出力) パラメーターを追加するときは、値 (初期化されたカーソル オブジェクトなど) ではなく、単にデータ型が必要なようです。

cmd.Parameters.Add("cur", Devart.Data.Oracle.OracleDbType.Cursor);
cmd.Parameters["cur"].Direction = ParameterDirection.Output;

(私は両方の方法を試しましたが、どちらもうまくいかなかったので...?)

本当に/したがって、私の質問は次のとおりです。これは、Cursorパラメーターをトラバーサル/アクセスのために出力することを宣言する本当に正しい方法ですか?

DevArt DotConnect コンポーネント (6.80.332)、VS 2010、.NET 4 の新しいバージョンを使用しています。

更新しました:

より詳細なコンテキストのコードは次のとおりです。

public void PopulateCurrentUserRoles(String AUserName, List<String> ACurrentUserRoles) { 
  _UserName = AUserName; 

  String query = "select roleid from ABCrole where ABCid = :ABCID"; 
  Devart.Data.Oracle.OracleCommand cmd = new Devart.Data.Oracle.OracleCommand(query, con); 
  cmd.CommandType = CommandType.Text; 
  int _ABCID = GetABCIDForUserName(); 

  cmd.Parameters.Add("cur", Devart.Data.Oracle.OracleDbType.Cursor); 
  cmd.Parameters["cur"].Direction = ParameterDirection.Output; 

  cmd.Parameters.Add("ABCID", _ABCID); 
  cmd.Parameters["ABCID"].Direction = ParameterDirection.Input; 
  cmd.Parameters["ABCID"].DbType = DbType.String; 
  //cmd.ExecuteNonQuery(); blows up: "illegal variable name/number" 
  //cmd.ExecuteCursor();   " " 
  //cmd.ExecuteReader();   " " 
  Devart.Data.Oracle.OracleCursor oraCursor = 
    (Devart.Data.Oracle.OracleCursor)cmd.Parameters["cur"].Value; 
  Devart.Data.Oracle.OracleDataReader odr = oraCursor.GetDataReader(); // "Object reference not set to an instance of an object" 
  while (odr.Read()) { 
    ACurrentUserRoles.Add(odr.GetString(0)); 
  } 
}
4

2 に答える 2

1

以下は、『Oracle Data Provider for .NET 開発者ガイド』からのものです。はい、私は知っています、「Devart」。それにもかかわらず、それは次のことを示唆しています。

  • パラメータの型宣言には注意してください。
  • そのカーソル/出力パラメーターを他のパラメーターより前にパラメーター コレクションに追加します。

ロングショットとして...私のガイドは を示してOracleDbType.RefCursorいますが、 ではありませんOracleDbType.Cursor。DevArt に RefCursor がある場合は、それを試してください。Visual Studio では、.NET はそのパラメーターがどの型であると考えていますか? この質問は、私が思っていたほど愚かではありません。

… 一方、OracleDbType プロパティの設定により、パラメータが OracleDbType.Char 型として設定されている場合、出力データは OracleString 型として返されます。コマンドの実行前に DbType プロパティと OracleDbType プロパティの両方が設定されている場合、最後の設定が有効になります。

. . .

「アプリケーションは出力パラメータの値をバインドするべきではありません。値オブジェクトを作成し、OracleParameter Valueプロパティにオブジェクトを移入するのはODP.NETの責任です。位置(デフォルト)によって関数にバインドする場合、ODP.NETは期待します。戻り値は、他のパラメータより前に最初にバインドされます。」


編集:

@Clayの自己回答に基づく...したがって、出力に指定されたパラメーターはなく、単にこれを行うだけです:OracleDataReader odr = cmd.ExecuteReader();

于 2012-03-29T17:51:34.010 に答える
0

馬の口から直接 (DevArt の人々):

_UserName = AUserName;
// From the DevArtisans:
String query = "select roleid from ABCrole where ABCid = :ABCID";
Devart.Data.Oracle.OracleCommand cmd = new Devart.Data.Oracle.OracleCommand(query, con);
cmd.CommandType = CommandType.Text;
int _ABCID = GetABCIDForUserName();
cmd.Parameters.Add("ABCID", _ABCID);
cmd.Parameters["ABCID"].Direction = ParameterDirection.Input;
cmd.Parameters["ABCID"].DbType = DbType.String;
Devart.Data.Oracle.OracleDataReader odr = cmd.ExecuteReader();
while (odr.Read()) {
  ACurrentUserRoles.Add(odr.GetString(0));
}

Casey and the Sonshine Banned を引用すると、「その通りだ、うーん、うーん、好きだ、うーん、うーん」。実際、私はそのがらくたを我慢できませんが、私は今のところその感情に少し関係しています.

于 2012-03-30T16:07:00.643 に答える