У меня есть эта функция 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;
Следующий код работает для меня.
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();
}
ODP.net связывается по заказу по умолчанию. Это поведение может быть изменено с помощью: cmd.BindByName = true
Насколько я помню Если вы используете 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