无法将“System.String”类型的对象转换为 C# 中的“Oracle.DataAccess.Client.OracleParameter”类型

Posted

技术标签:

【中文标题】无法将“System.String”类型的对象转换为 C# 中的“Oracle.DataAccess.Client.OracleParameter”类型【英文标题】:Unable to cast object of type 'System.String' to type 'Oracle.DataAccess.Client.OracleParameter' in C# 【发布时间】:2018-07-05 01:44:10 【问题描述】:

我试图在 C# 项目中调用一个存储过程,该过程除了返回 Oracle 11g 中的一些输入参数外,还返回 2 个值。 该过程是一个简单的登录,如果存储的用户与用户名和密码匹配,则返回 varchar2('T' 或 'F')(oracle 不接受布尔值?),并且它应该为用户类型返回一个数字(1 或 2)。

如果我仅使用 'pexito'(success) 输出参数测试程序,它可以工作,但它不能使用'ptipo'(用户类型))参数。

我尝试在 c# 代码中将 'ptipo' 参数的数据类型更改为 varchar2 和字符串,以不同的方式解析,转换为字符串,然后转换为 int 以及许多其他内容。没有任何效果,总是出现同样的错误。

“无法将“System.String”类型的对象转换为“Oracle.DataAccess.Client.OracleParameter”类型”

这是 PL/SQL SP 代码:

    CREATE OR REPLACE PROCEDURE sp_login
(puser IN VARCHAR2, ppass IN VARCHAR2,  pexito OUT VARCHAR2, ptipo OUT NUMBER )
AS
lfila NUMBER;
ltipo number;
BEGIN

SELECT COUNT(*)
INTO lfila
FROM usuario
WHERE user_login = puser AND pass_login = ppass;

SELECT idtipo_user
INTO ltipo
FROM usuario
WHERE user_login = puser AND pass_login = ppass;

IF lfila = 0 THEN pexito:='F';
ELSE pexito:='T';
END IF;

IF ltipo =NULL THEN ptipo:=NULL;
ELSE ptipo:=ltipo;
END IF;


END;
/

这里是 C# 代码:

using System;
using System.Data;
using System.Windows.Forms;
using Oracle.DataAccess.Client;
//using System.Data.OracleClient; DEPRECATED
using Sistema_On_Tour.Vistas;
using Sistema_On_Tour.Controlador;

    private void BtnIniciar_Click(object sender, EventArgs e)
            
                OracleConnection conn = new OracleConnection(Conexion.conn);

                try
                
                    conn.Open();
                    OracleCommand cmd = new OracleCommand("sp_login", conn);
                    cmd.CommandType = CommandType.StoredProcedure;

                    OracleParameter paruser = new OracleParameter("puser", OracleDbType.Varchar2);
                    paruser.Value= TxtUser.Text;
                    paruser.Direction = ParameterDirection.Input;
                    cmd.Parameters.Add(paruser);


                    OracleParameter parpass = new OracleParameter("ppass", OracleDbType.Varchar2);
                    parpass.Value = TxtPass.Text;
                    parpass.Direction = ParameterDirection.Input;
                    cmd.Parameters.Add(parpass);

                    OracleParameter parexito = new OracleParameter("pexito", OracleDbType.Varchar2);
                    parexito.Direction = ParameterDirection.Output;
                    parexito.Size = 1; 
                    cmd.Parameters.Add(parexito);

                    OracleParameter ptipo = new OracleParameter("ptipo", OracleDbType.Int32);
                    ptipo.Direction = ParameterDirection.Output;
                    ptipo.Size = 1; 
                    cmd.Parameters.Add("ptipo");

                    cmd.ExecuteNonQuery();
                    string exito = cmd.Parameters["pexito"].Value.ToString();
                    int tipouser = int.Parse(cmd.Parameters["ptipo"].Value.ToString());

                    if (exito.Equals('T'))
                    
                        if (tipouser == 1)
                        
                            this.Hide();
                            VentanaPrincipalApoderado v = new VentanaPrincipalApoderado();
                            v.Show();
                        
                        else if(tipouser==2)
                        
                            this.Hide();
                            VentanaPrincipalEjecutivo v = new VentanaPrincipalEjecutivo();
                            v.Show();
                        
                    


                    MessageBox.Show(exito);
                
                catch(Exception error)
                
                    MessageBox.Show(error.Message);

                
                finally
                
                    conn.Close();
                

            
        
     

【问题讨论】:

是的,OracleDbType 不支持布尔值,像你一样使用1/0T/F。两个小问题:IF ltipo = NULL从不为真,请改用IF ltipo IS NULL。我认为tipouser = Convert.ToInt32(cmd.Parameters["ptipo"].Value) 更可靠(不是int,而是一般) 谢谢!这在某种程度上也帮助了我! 【参考方案1】:

线路有问题

cmd.Parameters.Add("ptipo");

你必须这样做

   cmd.Parameters.Add(ptipo);

注意:您必须将变量而不是变量名称作为字符串传递。

【讨论】:

天哪,我不敢相信我错过了 Add 声明!非常感谢!我花了大约 3 个小时试图解决这个问题【参考方案2】:

这种事是行不通的

OracleParameter paruser = new OracleParameter("puser", OracleDbType.Varchar2);
                    paruser.Value= TxtUser.Text;
                    paruser.Direction = ParameterDirection.Input;
                    cmd.Parameters.Add(paruser);    

像下面的代码一样做,否则你会得到转换错误。

cmd.Parameters.Add("P_UserName", OracleDbType.Varchar2).Value = login.UserName;
cmd.Parameters.Add("P_UPassword", OracleDbType.Varchar2).Value = login.Password;
cmd.Parameters.Add("cur_splogin", OracleDbType.RefCursor).Direction = ParameterDirection.Output;

【讨论】:

以上是关于无法将“System.String”类型的对象转换为 C# 中的“Oracle.DataAccess.Client.OracleParameter”类型的主要内容,如果未能解决你的问题,请参考以下文章

提示:无法将类型为“System.DateTime”的对象强制转换为类型“System.String”。

无法将类型为“System.DateTime”的对象强制转换为类型“System.String”

无法将类型“System.String”的对象转换为类型“System.Byte []”错误 MYSQL NET CORE 3.1

无法将“System.String”类型的对象转换为“System.Int32”类型。关于 Blazor/Razor 路由参数

无法将“System.String”类型的对象转换为 C# 中的“Oracle.DataAccess.Client.OracleParameter”类型

无法将类型为“Newtonsoft.Json.Linq.JObject”的对象转换为类型“System.Collections.Generic.Dictionary`2[System.String,S