Выполнить функцию pl / sql с OracleCommand

4

У меня есть эта функция pl/sql, единственное, что она делает, - это проверка того, что пользователь существует в базе данных, если пользователь существует, это возвращает "Y", но если пользователь не существует, это возвращает "N", что я хочу получает значение, которое я возвращаю в 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 строк
  • 0
    Считать легче и лучше. SELECT IdEmpleado генерирует исключение NO_DATA_FOUND, если userName не существует или если пароль неправильный. SELECT count (*) возвращает 0.
Теги:
plsql
ado.net

3 ответа

6
Лучший ответ

Следующий код работает для меня.
NB: ваш код pl/sql, называемый функцией KRIST.f_Login, но ваш С# назвал его krist.p_login
NB2: ваш код pl/sql использовал Varchar2, но ваш С# использовал 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
    Примечание: возвращаемое значение должно быть добавлено в качестве первого параметра.
4

ODP.net связывается по заказу по умолчанию. Это поведение может быть изменено с помощью:   cmd.BindByName = true

  • 0
    Спасибо! ты спас мне кучу времени!
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 прекратит выполнение. Закройте его, как только он вам больше не понадобится.

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!
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню