为什么我的C#代码不能从我的Oracle函数中获得返回值?

时间:2014-06-17 12:55:30

标签: c# oracle function stored-procedures

我正在尝试检查用户是否在我的数据库中,我的函数的返回值是'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;

7 个答案:

答案 0 :(得分:1)

我暂时没有使用OracleCommands,但我建议这样做:

CommandText = "Login(:p_Naam, :p_Wachtwoord)";

我下注的长解决方案(虽然将类型更改为文本):

CommandText = "select Login(:p_Naam, :p_Wachtwoord) return_value from dual";

答案 1 :(得分:1)

如果您的代码中有此内容:

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();

答案 2 :(得分:1)

你需要在索引中首先放置“返回值”参数,据我所知,从使用Oracle时它没有将参数的名称传递给Oracle调用,它是绝对放置。

希望这能解决你的问题:)

的Dom

答案 3 :(得分:0)

ParameterDirection.ReturnValue只能返回一个数字值,而不是字符串或单个字符 (至少在Sql Server中)。尝试更改函数以返回整数和参数集合以接收整数。 (我没有Oracle测试,如果有一些语法错误,请纠正我)

See this reference (for 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...

答案 4 :(得分:0)

而不是'返回'声明为什么不宣布参数。让我知道如果我不清楚

答案 5 :(得分:0)

刚刚发现了这一点,并在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();
}

答案 6 :(得分:0)

使Return_Value为第一个参数:

cmd.Parameters.Add("Return_Value", OracleDbType.Boolean, ParameterDirection.ReturnValue);