2012-12-01 57 views
4

我有這個pl/sql函數,它唯一的作用是驗證用戶是否存在於數據庫中,如果用戶存在,則返回「Y」,但如果用戶不存在這個返回「N」,我想要的是得到我在pl/sql在c#中返回的值。使用OracleCommand執行pl/sql函數

我使用Oracle 10g

  CREATE OR REPLACE FUNCTION KRIST.f_Login (userName IN VARCHAR2, 
                 password IN VARCHAR2) 
      RETURN VARCHAR2 
      IS 
       CURSOR USERFINDER IS 
        SELECT IdEmpleado 
        FROM EMPLEADO 
        WHERE Usuario=userName 
        AND Clave=password; 
       id number; 
       returnVal VARCHAR2(1); 
      BEGIN 
       OPEN USERFINDER; 
       FETCH USERFINDER INTO id; 
       IF(id IS NULL) THEN 
        returnVal:='Y'; 
        RETURN returnVal; 
       END IF; 
       returnVal:='N'; 
       RETURN returnVal; 
       CLOSE USERFINDER; 
      END; 
      /

我怎樣才能實現這一功能,並在變量得到的結果...我有茨艾倫代碼,但不工作

   OracleCommand cmd = new OracleCommand("krist.p_login",conn); 
       cmd.CommandType = CommandType.StoredProcedure; // use StoredProcedure with Functions as well 
       OracleParameter returnVal = new OracleParameter("returnVal",null); 
       OracleParameter p_one = new OracleParameter("userName","kristian"); 
       OracleParameter p_two = new OracleParameter("password", "kristian"); 
       returnVal.OracleType = OracleType.VarChar; 
       returnVal.Size = 1; 
       p_one.OracleType = OracleType.VarChar; 
       p_two.OracleType = OracleType.VarChar; 
       p_one.DbType = DbType.String; 
       p_two.DbType = DbType.String; 
       returnVal.DbType = DbType.String; 
       returnVal.Direction = ParameterDirection.ReturnValue; 
       p_one.Direction = ParameterDirection.Input; 
       p_two.Direction = ParameterDirection.Input; 
       cmd.Parameters.Add(p_one); 
       cmd.Parameters.Add(p_two); 
       cmd.Parameters.Add(returnVal); 
       cmd.ExecuteNonQuery(); 
       String bval = Convert.ToString(returnVal.Value); 
       return bval; 
+3

確實更容易,使用count(*)並查看返回的行是否超過0行 – Andrew

+0

計數更容易,更好。如果userName不存在或者密碼錯誤,則SELECT IdEmpleado將引​​發NO_DATA_FOUND豁免。 SELECT COUNT(*)返回0 –

回答

6

以下代碼適用於我。
注:您的PL/SQL代碼調用的函數KRIST.f_Login,但你的C#稱它爲krist.p_login
NB2:你的PL/SQL代碼中使用VARCHAR2,但你的C#中使用VARCHAR
NB3:我使用的是Oracle。 DataAccess.dll
NB4:我假設你的返回值緩衝區大小可能是1,但嘗試不同的大小。

using Oracle.DataAccess.Client; 
using Oracle.DataAccess.Types; 

int RETURN_VALUE_BUFFER_SIZE = 32767; 
OracleCommand cmd = new OracleCommand(); 
try { 
    cmd.Connection = conn; 
    cmd.CommandText = "KRIST.f_Login"; 
    cmd.CommandType = CommandType.StoredProcedure; 

    cmd.Parameters.Add("returnVal", OracleDbType.Varchar2, RETURN_VALUE_BUFFER_SIZE); 
    cmd.Parameters["returnVal"].Direction = ParameterDirection.ReturnValue; 

    cmd.Parameters.Add("userName", OracleDbType.Varchar2); 
    cmd.Parameters["userName"].Value = "kristian"; 

    cmd.Parameters.Add("password", OracleDbType.Varchar2); 
    cmd.Parameters["password"].Value = "kristian"; 

    cmd.ExecuteNonQuery(); 
    string bval = cmd.Parameters["returnVal"].Value.ToString(); 
    return bval; 
} catch (Exception e) { 
    // deal with exception 
} finally { 
    command.Dispose(); 
    connection.Close(); 
    connection.Dispose(); 
} 
+1

注意:返回值必須作爲第一個參數添加。 – Altivo

3

至於我請記住如果您使用ODP.NET,則需要首先提供retVal參數。

ODP.NET有些問題,它不會將參數與提供的參數名稱綁定,而是與參數順序綁定。

所以,簡單地順序更改爲:

cmd.Parameters.Add(returnVal); 
cmd.Parameters.Add(p_one); 
cmd.Parameters.Add(p_two); 

而且在我的消息來源,我發現返回參數我所謂的「RETURN」(不知道這是否計數):

OracleParameter returnVal = new OracleParameter("RETURN",null); 

哈哈,一個更多的事情。它永遠不會到達最後一行 - cuase返回將終止執行。一旦你不再需要它就關閉它。

RETURN returnVal; 
CLOSE USERFINDER; --<<-- won't close this cursor 
+1

ORA-06550:第1行,第18欄: PLS-00306:錯誤數量或類型的在調用 'P_LOGIN' ORA-06550參數:第1行,第7列: 這是引發異常 –

+0

你在PL/SQL中的函數被稱爲F_LOGIN,而在.NET中,你正試圖調用P_LOGIN! –

+0

沒有好的xD ....但在我試圖做一個過程中,我試圖做一個過程中,出變量,它不工作,但應該是p_login –

4

ODP.net按默認順序綁定。此行爲可以通過以下方式進行修改: cmd.BindByName = true

+0

謝謝!你爲我節省了一筆時間! –