【问题标题】:Return sys_refcursor of the oracle to c#将oracle的sys_refcursor返回给c#
【发布时间】:2016-01-02 09:23:35
【问题描述】:

C#:

 public DataSet ListaClientes()
    {
        DataSet ds = new DataSet();
        try
        {
            System.Data.OracleClient.OracleConnection conexion = Conexion.GetConnection();
            if (conexion.State == System.Data.ConnectionState.Open)
            {
                System.Data.OracleClient.OracleCommand cmd = new System.Data.OracleClient.OracleCommand();
                cmd.Connection = conexion;
                cmd.CommandText = "ListadoClientes";
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.Parameters.Add("resul", OracleDbType.RefCursor).Direction = ParameterDirection.Output;
                cmd.ExecuteNonQuery();
                conexion.Close();
                System.Data.OracleClient.OracleDataAdapter da = new System.Data.OracleClient.OracleDataAdapter(cmd);                    
                da.Fill(ds);                    
            }
            return ds;
        }
        catch(Exception e)
        {
            throw e;
        }
    }

Oracle 存储过程:

CREATE OR REPLACE PROCEDURE ListadoClientes(resul OUT sys_refcursor)
IS 
BEGIN 
  OPEN resul for select ID ,NOMBRES ,APELLIDOS ,CEDULA ,DIRECCION ,TELEFONO  
  from cliente; 
END ListadoClientes;

从 C# CATCH 块中可见的错误:

ORA-06550: line 1, column 7: 
PLS-00306: wrong number or types of arguments in call to 'LISTADOCLIENTES' 
ORA-06550: line 1, column 7: PL/SQL: Statement ignored

【问题讨论】:

    标签: c# oracle stored-procedures oracle11g


    【解决方案1】:

    你不使用函数而不是过程有什么原因吗?

    CREATE OR REPLACE FUNCTION ListadoClientes() RETURN sys_refcursor
    IS 
    resul Sys_refcursor;
    BEGIN 
      OPEN resul for select ID ,NOMBRES ,APELLIDOS ,CEDULA ,DIRECCION ,TELEFONO  
      from cliente; 
      RETURN resul;
    END ListadoClientes;
    

    然后在 C# 中你必须将其更改为:

    cmd.Parameters.Add("resul", OracleDbType.RefCursor, ParameterDirection.ReturnValue);
    

    当您运行da.Fill(ds); 时,该函数会被执行,即使用cmd.ExecuteNonQuery(); 会执行该函数两次。

    无论如何,对于一个程序,正确的方法应该是这个:

    cmd.CommandText = "ListadoClientes(:resul)";
    

    【讨论】:

      【解决方案2】:

      最后,我设法使它以这种方式工作:

      存储过程

      create or replace PROCEDURE ListadoClientes(resul OUT sys_refcursor) IS BEGIN   OPEN resul for select ID ,NOMBRES ,APELLIDOS ,CEDULA ,DIRECCION ,TELEFONO  from cliente; END ListadoClientes;
      

      源代码

      reference using Oracle.DataAccess.Client;
      public DataSet ListaClientes()
          {
              DataSet ds = new DataSet();
              try
              {
                  OracleConnection conexion = Conexion.GetConnection2();
                  if (conexion.State == System.Data.ConnectionState.Open)
                  {
                      OracleCommand  cmd = new OracleCommand();
                      cmd.Connection = conexion;
                      cmd.CommandText = "ListadoClientes";
                      cmd.CommandType = CommandType.StoredProcedure;
                      cmd.Parameters.Add("resul", OracleDbType.RefCursor).Direction = ParameterDirection.Output;                    
                      cmd.ExecuteNonQuery();
                      conexion.Close();
                      OracleDataAdapter  da = new OracleDataAdapter(cmd);                    
                      da.Fill(ds);
                  }
                  return ds;
              }
              catch(Exception e)
              {
                  throw e;
              }
          }
      

      【讨论】:

        猜你喜欢
        • 2021-06-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多