【问题标题】:Is a cursor parameter really to be declared differently than a "regular" parameter?游标参数的声明真的与“常规”参数不同吗?
【发布时间】:2012-04-13 09:23:50
【问题描述】:

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

我以这种方式将 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)); 
  } 
}

【问题讨论】:

  • 你为什么使用光标?游标(通常)是您在 SQL 中可以做的最糟糕的事情?我建议使用 WHILE 循环重新查看 SQL AND/OR。请记住,SQL 是基于 SET 的逻辑,而不是过程。如果你循环很多,那么你应该在你的代码中这样做,而不是 SQL
  • “两者都不起作用”并不能真正解释您在尝试时观察到的情况......
  • @Jon:如果我调用 ExecuteNonQuery() - 这似乎是共识,虽然这对我来说毫无意义,因为我的 SQL 语句是一个查询(选择) - 我得到,“非法变量姓名/号码”。如果我将 ExecuteNonQuery() 注释掉,我会在调用 GetDataReader() 时得到“对象引用未设置为对象的实例”
  • @Justin:我正在尝试使用 while 循环,这就是我对 Oracle 的 ODP 组件所做的事情。我没有看到如何使用 DotConnect 组件来做到这一点。
  • @ClayShannon:你没有显示调用GetDataReader的代码,这很难说发生了什么......

标签: c# oracle devart dotconnect


【解决方案1】:

以下内容来自Oracle Data Provider for .NET 开发人员指南。是的,我知道,“Devart”。尽管如此,它提出了以下建议:

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

从长远来看...我的指南显示OracleDbType.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();

【讨论】:

  • “小心你的参数类型声明”——意思是……?
  • 有一个“Ref”但没有“RefCursor”。用 .Ref 替换 .Cursor 没有任何区别(相同的错误消息)。
  • 我见过的 DotConnect 示例都是关于使用 DataAdapter、填充它,然后为网格提供该数据。我开始认为我将不得不做类似的事情,然后遍历数据集(我不应该需要哪个中间人)来填充我的字符串列表...啊啊啊
【解决方案2】:

直接从马的嘴里(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的话,“就是这样,嗯嗯嗯嗯,我喜欢,嗯嗯嗯嗯”;实际上,我无法忍受这种废话,但我现在确实有点与这种情绪有关。

【讨论】:

    猜你喜欢
    • 2010-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-16
    • 2019-08-21
    • 2017-11-29
    • 2016-07-08
    • 1970-01-01
    相关资源
    最近更新 更多