0

好的,似乎没有人知道如何解决我在循环游标/结果集以存储到列表中时遇到的问题,所以我将把它分解成碎片并尝试以这种方式通过它。所以,首先:

我以这种方式将 SQL 参数添加到 OracleCommand 对象(工作正常):

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

IOW,当我添加参数时,我传递了 SQL 的参数化部分的名称(上面的“ABCID”)和一个值(_ABCID 是一个已分配的变量,比如“42”)。

但是,当添加一个 Cursor(输出)参数时,它似乎想要的,不是一个值(例如初始化的游标对象),而只是数据类型:

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

(我两种方法都试过了,都不管用,所以...?)

确实/因此,我的问题是:这真的是声明要输出回用于遍历/访问的游标参数的正确方法吗?

我正在使用全新版本的 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 Developer's Guide。是的,我知道,“Devart”。尽管如此,它提出了以下建议:

  • 小心你的参数类型声明。
  • 在任何其他参数之前将该光标/输出参数添加到参数集合中。

作为一个长镜头......我的指南显示 aOracleDbType.RefCursor但不是OracleDbType.Cursor. 如果 DevArt 有 RefCursor,试试看。在 Visual Studio 中,.NET 认为该参数是什么类型?这个问题并不像我以前想的那么愚蠢。

...另一方面,如果通过设置 OracleDbType 属性将参数设置为 OracleDbType.Char 类型,则输出数据将作为 OracleString 类型返回。如果在命令执行之前同时设置了 DbType 和 OracleDbType 属性,则最后一个设置生效。

. . .

“应用程序不应为输出参数绑定值;ODP.NET 有责任创建值对象并使用该对象填充 OracleParameter Value 属性。当按位置(默认)绑定到函数时,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 回答