使用 Oracle 存储过程中的 refcursor 值填充 C# 数据表

Posted

技术标签:

【中文标题】使用 Oracle 存储过程中的 refcursor 值填充 C# 数据表【英文标题】:Populating C# datatable with refcursor values from an Oracle Stored Procedure 【发布时间】:2014-04-20 06:50:56 【问题描述】:

我希望使用存储过程“spValidateDBA”中的 refcursor 参数 UserRole 的值填充数据表,但它每次都给我这个错误:

列“UserRole”不属于表。

C#代码:-

string sConnectionString = "Data Source=XE;User ID=sys;Password=system;DBA PRIVILEGE=sysdba";
        OracleConnection myConnection = new OracleConnection(sConnectionString);
        OracleCommand myCommand = new OracleCommand("spValidateDBA", myConnection);
        myCommand.CommandType = CommandType.StoredProcedure;
        myCommand.CommandText = "spValidateDBA";
        myCommand.Parameters.Add("UserId", OracleDbType.Varchar2, 50);
        myCommand.Parameters["UserId"].Value = txtUsrId.Text.ToString().ToUpper();
        myCommand.Parameters.Add("UserRole",OracleDbType.RefCursor, 50).Direction = ParameterDirection.Output;
        myCommand.Parameters.Add("UserIdOut", OracleDbType.Varchar2, 50).Direction = ParameterDirection.Output;
        var rolechk = false;
        string checkrole = "DBA";
       myConnection.Open();
       myCommand.ExecuteReader();
        // Create the OracleDataAdapter
        OracleDataAdapter da = new OracleDataAdapter(myCommand);
        DataTable dt = new DataTable();
        da.Fill(dt);  // Trying to populate a DataTable with refcursor UserRole.
        if (myCommand.Parameters["UserIdOut"].Value.ToString().ToUpper() == txtUsrId.Text.ToString().ToUpper())
            
                CustomMsgbox.Show("1", "DB Utilities Tool", "OK", "Cancel");
                foreach (DataRow dr in dt.Rows)
                
                    if (dr["UserRole"].ToString().ToUpper().Equals(checkrole)==true)//getting the error "Column 'UserRole' does not belong to table." here
                   

                        CustomMsgbox.Show("\tLogin Successful..!!\t" + Environment.NewLine + "Welcome to DB Utilities Tool", "DB Utilities Tool", "OK", "Cancel");
                        DBA dba = new DBA();
                        dba.Show();
                        this.Hide();
                        rolechk = true;
                        break;

                    
                

                if (!rolechk)
                

                    CustomMsgbox.Show("Insufficient privileges", "DB Utilities Tool", "OK", "Cancel");
                    myConnection.Close();
                


        else
            CustomMsgbox.Show("Please enter correct User ID/Password", "DB Utilities Tool", "OK", "Cancel");

    

存储过程 spValidateDBA

create or replace PROCEDURE spValidateDBA(
    UserId IN VARCHAR2,
UserRole OUT SYS_REFCURSOR,
 UserIdOut OUT VARCHAR2)
  AS
BEGIN
select USERNAME into UserIdOut from DBA_USERS DU where DU.USERNAME=UserId;
OPEN UserRole FOR
select GRANTED_ROLE from DBA_USERS DU,DBA_ROLE_PRIVS DRP where DU.USERNAME=UserId AND DU.USERNAME=DRP.GRANTEE;
  END spValidateDBA;

【问题讨论】:

【参考方案1】:

您在游标查询中仅检索一列 GRANTED_ROLE

打开用户角色 FOR 从 DBA_USERS DU 中选择 GRANTED_ROLE,.......

但是您尝试从游标中获取 UserRole 列。

if (dr["UserRole"].ToString().ToUp.........

那里没有UserRole的列,只能取GRANTED_ROLE

【讨论】:

感谢伙伴指出错误,你是救命稻草。我错误地考虑了数据表列名称的游标名称,而不是从存储过程中获取的实际数据库列,谢谢一次再次,非常感谢您的帮助..!!!

以上是关于使用 Oracle 存储过程中的 refcursor 值填充 C# 数据表的主要内容,如果未能解决你的问题,请参考以下文章

oracle中的存储过程有啥作用,该怎么理解?(数据更新的话用update语句不就完了吗)

oracle的存储过程

Oracle 存储过程在 Informatica 存储过程转换映射中的会话结束时运行

oracle中的存储过程怎么写

oracle中的存储过程,用于根据行获取记录

使用 Oracle 存储过程中的 refcursor 值填充 C# 数据表