2012-03-29 54 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