2012-12-01 38 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

谢谢!你为我节省了一笔时间! –