2012-03-29 53 views
0

好吧,似乎没有人知道如何解决我通过游标/结果集循环访问存储到列表中的问题,所以我打算将它分解成几部分,并试图通过这种方式来琢磨。所以,首先:是否真的要将游标参数声明为与“常规”参数不同?

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

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

督察,当我添加帕拉姆,我传递的参数化部分的名称SQL(上面的“ABCID”)和赋予它的值(_ABCID是已分配的变量,比方说,“42”)。

然而,添加一个光标(输出)PARAM时,它似乎想,而不是一个值(如初始化的光标对象),而是简单的数据类型:

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)); 
    } 
} 
+0

你为什么使用游标?游标是(通常)在SQL中可以做的最糟糕的事情?我建议在SQL AND/OR中使用WHILE循环重新查看。请记住,SQL是基于SET的逻辑,而不是程序性的。如果你循环繁琐,那么你应该在你的代码中这样做,而不是SQL – 2012-03-29 17:28:48

+0

“没有人工作”并不能真正解释你在尝试时观察到的内容...... – 2012-03-29 17:29:37

+0

@Jon:如果我调用ExecuteNonQuery() - 这似乎是共识,虽然它对我来说没有意义,因为我的SQL语句是查询(Select) - 我得到“非法变量名称/数字”。我调用GetDataReader() – 2012-03-29 18:58:19

回答

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)); 
} 

要引用Ca sey和Sonshine被禁止,“这就是方式,嗯,嗯,我喜欢它,嗯,嗯”;实际上,我无法忍受那种废话,但我现在确实与这种情绪有关。

1

以下内容来自适用于.NET的Oracle数据提供程序开发人员指南。是的,我知道,“Devart”。尽管如此,它建议如下:

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

作为一个远投......我的向导显示OracleDbType.RefCursor但不是OracleDbType.Cursor。如果DevArt具有RefCursor,请尝试。在Visual Studio中,.NET认为参数是什么类型?这个问题不像我以前想的那样愚蠢。

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

。 。 。

“的应用程序不应该结合对输出参数的值;它是 ODP.NET的负责创建值对象并填充 与对象的的OracleParameter Value属性当由 位置(默认)来结合。一个函数,ODP.NET预计返回值为 先被绑定,然后是任何其他参数。“


编辑:

基于@粘土的自我答案......所以没有为输出指定的参数,而不是简单地一个做到这一点:OracleDataReader odr = cmd.ExecuteReader();

+0

“小心你的参数类型声明” - 意思是......? – 2012-03-29 19:21:28

+0

有一个“Ref”,但没有“RefCursor”。用.Ref替换.Cursor没有区别(同样的错误信息)。 – 2012-03-29 19:30:51

+0

我见过的DotConnect示例都是关于使用DataAdapter,填充它,然后为这个数据提供一个网格。我开始认为我将不得不做那样的事情,然后遍历数据集(我不应该需要的中间人)来填充我的字符串列表... arghhhh – 2012-03-29 22:03:43