2009-06-06 197 views
11

有了這個C#Oracle存儲過程參數順序

PROCEDURE "ADD_BOOKMARK_GROUP" (
    "NAME" IN VARCHAR2, 
    "BOOKMARK_GROUP_ID" IN NUMBER, 
    "STAFF_ID" IN VARCHAR2, 
    "MAX_NO" IN INT, 
    "NUMFOUND" OUT INT, 
    "NEW_ID" OUT NUMBER) IS 

BEGIN 

NEW_ID := -1; 

SELECT COUNT(*) INTO NUMFOUND FROM BOOKMARK_GROUP_TABLE WHERE STAFF_ID = STAFF_ID; 

IF NUMFOUND < MAX_NO THEN 
    INSERT INTO BOOKMARK_GROUP_TABLE (NAME, BOOKMARK_GROUP_ID, STAFF_ID) VALUES(NAME, BOOKMARK_GROUP_ID, STAFF_ID); 
    SELECT BGT_SEQUENCE.currval INTO NEW_ID FROM dual; 
END IF; 
END; 

我覺得很有意思,如果我不按順序添加參數,他們被定義,例如

OracleCommand cmd = new OracleCommand("ADD_BOOKMARK_GROUP", conn); 
cmd.CommandType = CommandType.StoredProcedure; 
cmd.Parameters.Add(new OracleParameter("NAME", name)); 
... 
cmd.Parameters.Add(new OracleParameter("NEW_ID", OracleDbType.Decimal)).Direction = ParameterDirection.Output; 
cmd.Parameters.Add(new OracleParameter("NUMFOUND", OracleDbType.Int32)).Direction = ParameterDirection.Output; 

代替

OracleCommand cmd = new OracleCommand("ADD_BOOKMARK_GROUP", conn); 
cmd.CommandType = CommandType.StoredProcedure; 
cmd.Parameters.Add(new OracleParameter("NAME", name)); 
... 
cmd.Parameters.Add(new OracleParameter("NUMFOUND", OracleDbType.Int32)).Direction = ParameterDirection.Output; 
cmd.Parameters.Add(new OracleParameter("NEW_ID", OracleDbType.Decimal)).Direction = ParameterDirection.Output; 

通過

cmd.Parameters["NEW_ID"].Value.ToString() 

cmd.Parameters["NUMFOUND"].Value.ToString() 

返回的值被換,雖然運行通過VS2008服務器資源管理器程序返回正確的數據。

這是爲什麼?

回答

10

我不是Oracle愛好者,所以我無法驗證 - 但它聽起來像像他們正在傳遞的位置(而不是通過名稱傳遞)。道德equivelent到:而不是

EXEC SomeProc 'Foo', 'Bar' 

EXEC SomeProc @arg1='Foo', @arg2='Bar' 

這不是巨大的罕見 - 年(在COM天),我的很多代碼曾與一個傳遞工作位ADODB驅動程序。

在這種情況下,您提供的名稱服務只有作爲本地鍵來查找集合集合中的值。您可以通過發明的名稱很容易地驗證:

cmd.Parameters.Add(new OracleParameter("BANANA", ... 
cmd.Parameters.Add(new OracleParameter("GUITAR", ... 
... 
cmd.Parameters["BANANA"].Value.ToString() 
cmd.Parameters["GUITAR"].Value.ToString() 

如果沒有錯誤以上運行時,它是由位置傳遞。他們通過位置...然後只需將它們按正確的順序添加; -p並且永遠不會添加新的參數,除了最後...

+0

因此,它們按位置傳遞,雖然名稱會很多更有用。 – 2009-06-06 08:56:46

24

你或許可以設置OracleCommand對象上BindByName參數。這適用於帶有參數的直接SQL查詢,我沒有使用存儲過程嘗試過,但它是合乎邏輯的...

cmd.BindByName = true; 
+5

這是真正的答案。應該被接受。 – 2009-10-28 19:08:00