为什么我的c#代码不能从我的Oracle函数中获得返回值?
本文关键字:我的 返回值 函数 Oracle 代码 不能 为什么 | 更新日期: 2023-09-27 18:08:53
我试图检查用户是否在我的数据库中,我的函数返回值是't'或'f'。如下:
CREATE OR REPLACE FUNCTION LOGIN
(p_Naam in varchar2
,p_Wachtwoord in varchar2)
return varchar2
is
v_count number;
BEGIN
select count(*) into v_count
from Lid
where Naam = p_Naam
and Wachtwoord = p_Wachtwoord;
if v_count > 0 then
return 't';
end if;
return 'f';
END LOGIN;
现在我用c#代码调用这个函数,如下所示:
public bool LogIn(string gebruikersnaam, string wachtwoord)
{
string s;
var cmd = new OracleCommand
{
Connection = conn,
CommandText = "Login",
CommandType = CommandType.StoredProcedure
};
cmd.Parameters.Add("p_Naam", OracleDbType.Varchar2).Value = gebruikersnaam;
cmd.Parameters.Add("p_Wachtwoord", OracleDbType.Varchar2).Value = wachtwoord;
cmd.Parameters.Add("return_value", OracleDbType.Varchar2, ParameterDirection.ReturnValue);
try
{
conn.Open();
cmd.ExecuteNonQuery();
s = cmd.Parameters["return_value"].Value.ToString();
}
finally
{
conn.Close();
}
return s == "t";
}
当我在oracle开发人员中尝试此函数时,我得到一个输出。只有在我的c#代码中,s总是显示为"
在我的SQL开发程序中,下面给我't'
BEGIN
dbms_output.put_line(LOGIN('Willem Koonings', 'willem'));
END;
我已经有一段时间没有使用oracleccommands了,但我建议这样做:
CommandText = "Login(:p_Naam, :p_Wachtwoord)";
我打赌长的解决方案是有效的(将类型更改为文本):
CommandText = "select Login(:p_Naam, :p_Wachtwoord) return_value from dual";
当你在你的代码中有这个:
s = cmd.Parameters["return_value"].Value.ToString();
对我来说,它暗示你的命令有类似于这样的想法:
insert into test (user_name, create_date)
values (:USERNAME, sysdate)
returning user_id into :return_value
我从未见过一个存储过程像这样使用"返回"。这并不意味着它不能被完成,但它似乎与我使用它和看到它被使用的方式不一致。
由于您正在运行一个返回标量值的存储过程,因此这可能更适合您:
string result = (string)cmd.ExecuteScalar();
你需要把"return value"参数放在索引的第一个,据我所知,从Oracle的工作中,它不会把参数的名字传递给Oracle调用,它是绝对的放置。
希望这能解决你的问题。
DomParameterDirection.ReturnValue
只能返回一个数值,不能返回字符串或单个字符。
(至少在Sql Server中是这样)。尝试将函数更改为返回一个整数,并将参数集合更改为接收一个整数。(我没有Oracle测试,如果有语法错误请纠正我)
参见此参考(Sql Server)
CREATE OR REPLACE FUNCTION LOGIN
(p_Naam in varchar2
,p_Wachtwoord in varchar2)
return INTEGER
is
v_count number;
BEGIN
select count(*) into v_count
from Lid
where Naam = p_Naam
and Wachtwoord = p_Wachtwoord;
if v_count > 0 then
return 1;
end if;
return 0;
END LOGIN;
....
cmd.Parameters.Add("p_Naam", OracleDbType.Varchar2).Value = gebruikersnaam;
cmd.Parameters.Add("p_Wachtwoord", OracleDbType.Varchar2).Value = wachtwoord;
cmd.Parameters.Add("return_value", OracleDbType.Int32, ParameterDirection.ReturnValue);
....
int result = Convert.ToInt32(cmd.Parameters["return_value"].Value);
if(result == 0)
// fail
else
// success...
为什么不声明一个out参数而不是'Return'语句呢?如果我不清楚,请告诉我
刚刚发现了这个问题,并在VS2017社区版+ 11g上进行了测试。
OracleCommand chkCmd = null;
try
{
chkCmd = new OracleCommand();
chkCmd.CommandText = "login";
chkCmd.CommandType = CommandType.StoredProcedure;
chkCmd.Connection = conn;
OracleParameter mobParam1 = new OracleParameter("p_Naam", OracleDbType.Varchar2, 2000);
mobParam1.Direction = ParameterDirection.Input;
mobParam1.Value = gebruikersnaam;
OracleParameter mobParam2 = new OracleParameter("p_Wachtwoord", OracleDbType.Varchar2, 2000);
mobParam2.Direction = ParameterDirection.Input;
mobParam2.Value = wachtwoord;
OracleParameter retValue = new OracleParameter("returnVal", OracleDbType.Varchar2, 2000);
retValue.Direction = ParameterDirection.ReturnValue;
chkCmd.Parameters.Clear();
chkCmd.Parameters.Add(retValue);
chkCmd.Parameters.Add(mobParam1);
chkCmd.Parameters.Add(mobParam2);
con.Open();
chkCmd.ExecuteScalar();
string retmsg = Convert.ToString(retValue.Value);
return retmsg=="t";
}
finally
{
con.Close();
chkCmd.Dispose();
con.Dispose();
}
将Return_Value
作为第一个参数:
cmd.Parameters.Add("Return_Value", OracleDbType.Boolean, ParameterDirection.ReturnValue);