Pergunta

Quero retornar dados de um procedimento Oracle para preencher alguns controles de etiquetas. O procedimento aceita 26 parâmetros de entrada (variável de pesquisa) e retorna 3 cursores de saída. Fiquei com sucesso devolver dados de um procedimento que retorna um único cursor de ref usando o OracleCommand, um DataAdapter e um conjunto de dados, mas tenho tido todos os tipos de problemas devolvendo dados de um procedimento que retornando vários cursores de referência.

Eu estava tentando usar o Daab na biblioteca corporativa, mas não tive sucesso (postagem original). Agora voltei a um OracleCommand com base nas postagens da Oracle e de outros sites DV. Ainda estou retornando zero linhas. Posso devolver os nomes das colunas dos meus leitores usando "rdr_p_cursor_detail.getName (0);", mas quando tento retornar um valor, recebo uma "operação não é válida devido ao estado atual do objeto". erro.

        //Open the connection to Oracle.
        OracleConnection cn = new OracleConnection(ConfigurationHelper.ConnectionStringSlabProcedures);
        OracleCommand cmd = new OracleCommand();
        cn.Open();
        cmd.Connection = cn;


        try
        {

            //Set the command text (SQL) of the Oracle command to the stored procedure "getSlab", which returns slab details.
            cmd.CommandText = ConfigurationHelper.ProcuedurePackageSchema + "." +
                              ConfigurationHelper.ProcuedurePackageName + "." +
                              "getSlab";
            //...and specify the command as a stored procedure.
            cmd.CommandType = CommandType.StoredProcedure;


            //Add the input and output parameters.  
            cmd.Parameters.Add("rb_category", OracleDbType.Varchar2).Value = string.Empty;
            cmd.Parameters.Add("rb_category_value", OracleDbType.Varchar2).Value = slabID;
            cmd.Parameters.Add("rb_type ", OracleDbType.Varchar2).Value = string.Empty;
            cmd.Parameters.Add("rb_chem_value", OracleDbType.Varchar2).Value = string.Empty;
            cmd.Parameters.Add("cb_inside_only", OracleDbType.Varchar2).Value = string.Empty;
            cmd.Parameters.Add("cb_appl_pending", OracleDbType.Varchar2).Value = string.Empty;
            cmd.Parameters.Add("cb_appl_soft_approved", OracleDbType.Varchar2).Value = string.Empty;
            cmd.Parameters.Add("cb_appl_hard_approved", OracleDbType.Varchar2).Value = string.Empty;
            cmd.Parameters.Add("cb_appl_mechanically", OracleDbType.Varchar2).Value = string.Empty;
            cmd.Parameters.Add("cb_as_cast", OracleDbType.Varchar2).Value = string.Empty;
            cmd.Parameters.Add("cb_as_dispoed", OracleDbType.Varchar2).Value = string.Empty;
            cmd.Parameters.Add("cb_chem_match", OracleDbType.Varchar2).Value = string.Empty;
            cmd.Parameters.Add("cb_near_match", OracleDbType.Varchar2).Value = string.Empty;
            cmd.Parameters.Add("txt_width_min", OracleDbType.Int32).Value = 0;
            cmd.Parameters.Add("txt_width_max", OracleDbType.Int32).Value = 0;
            cmd.Parameters.Add("txt_quality_min", OracleDbType.Int32).Value = 0;
            cmd.Parameters.Add("txt_quality_max", OracleDbType.Int32).Value = 0;
            cmd.Parameters.Add("txt_days_old_min", OracleDbType.Int32).Value = 0;
            cmd.Parameters.Add("txt_days_old_max", OracleDbType.Int32).Value = 0;
            cmd.Parameters.Add("txt_days_rev_min", OracleDbType.Int32).Value = 0;
            cmd.Parameters.Add("txt_days_rev_max", OracleDbType.Int32).Value = 0;
            cmd.Parameters.Add("txt_reviewer", OracleDbType.Varchar2).Value = string.Empty;
            cmd.Parameters.Add("cb_excl_hr", OracleDbType.Varchar2).Value = string.Empty;
            cmd.Parameters.Add("cb_excl_cr", OracleDbType.Varchar2).Value = string.Empty;
            cmd.Parameters.Add("cb_excl_galv", OracleDbType.Varchar2).Value = string.Empty;
            cmd.Parameters.Add("cb_excl_tin", OracleDbType.Varchar2).Value = string.Empty;



            //Add the ref-cursors as output parameters
            OracleParameter p_cursor_detail = cmd.Parameters.Add("p_cursor_detail", OracleDbType.RefCursor);
            p_cursor_detail.Direction = ParameterDirection.Output;

            OracleParameter p_cursor_comments = cmd.Parameters.Add("p_cursor_comments", OracleDbType.RefCursor);
            p_cursor_comments.Direction = ParameterDirection.Output;

            OracleParameter p_cursor_grades = cmd.Parameters.Add("p_cursor_grades", OracleDbType.RefCursor);
            p_cursor_grades.Direction = ParameterDirection.Output;

            // Execute the command
            cmd.ExecuteNonQuery();


            // Construct an OracleDataReader from the REF CURSOR
            OracleDataReader rdr_p_cursor_detail = ((OracleRefCursor)p_cursor_detail.Value).GetDataReader();

            if (rdr_p_cursor_detail.Read())
            {

                //This would return an error if it was outside this if statement.
                //"Operation is not valid due to the current state of the object."
                OracleString oracleString1 = rdr_p_cursor_detail.GetOracleString(1);
                LabelSlabID.Text = oracleString1.ToString();

                //This correctly returns column name/header.
                //LabelSlabID.Text = rdr_p_cursor_detail.GetName(0);

            }
            else
            {
                LabelSlabID.Text = "No Data";
            }



            rdr_p_cursor_detail.Close();
            rdr_p_cursor_detail.Dispose();

            p_cursor_detail.Dispose();
            p_cursor_comments.Dispose();
            p_cursor_grades.Dispose();

        }
        catch (Exception e)

O procedimento Oracle truncado:

PROCEDURE getSlab         
(rb_category                  IN VARCHAR2
,rb_category_value        IN VARCHAR2
,rb_type                      IN VARCHAR2
,rb_chem_value            IN VARCHAR2                                
,cb_inside_only           IN VARCHAR2     
,cb_appl_pending          IN VARCHAR2   
,cb_appl_soft_approved    IN VARCHAR2   
,cb_appl_hard_approved    IN VARCHAR2             
,cb_appl_mechanically     IN VARCHAR2   
,cb_as_cast                   IN VARCHAR2   
,cb_as_dispoed            IN VARCHAR2   
,cb_chem_match            IN VARCHAR2   
,cb_near_match            IN VARCHAR2   
,txt_width_min            IN NUMBER
,txt_width_max            IN NUMBER
,txt_quality_min          IN NUMBER
,txt_quality_max          IN NUMBER
,txt_days_old_min         IN NUMBER
,txt_days_old_max         IN NUMBER     
,txt_days_rev_min         IN NUMBER
,txt_days_rev_max         IN NUMBER
,txt_reviewer             IN VARCHAR2         
,cb_excl_hr               IN VARCHAR2
,cb_excl_cr               IN VARCHAR2
,cb_excl_galv             IN VARCHAR2
,cb_excl_tin                  IN VARCHAR2
,cur_OUT OUT t_cursor1 
,cur_OUT1 OUT t_cursor2
,cur_OUT2 OUT t_cursor3) IS


 --All the queries and so forth are performed and data sent to temp tables.
  OPEN v_cursor1 FOR
        SELECT * FROM TABLE(CAST(g_slab_table AS getSlab_table));
    cur_OUT := v_cursor1;   

  OPEN v_cursor2 FOR
         SELECT * FROM TABLE(CAST(g_comment_table AS getComment_table));
    cur_OUT1 := v_cursor2;      

  OPEN v_cursor3 FOR
         SELECT * FROM TABLE(CAST(g_grades_table AS getGrades_table));
    cur_OUT2 := v_cursor2;      

Alguma ideia? Estou inclinado para o uso inadequado do leitor, mas não consigo descobrir o que estou perdendo. Obrigado.

Foi útil?

Solução

Parece ser o procedimento armazenado do Oracle. Modifiquei a saída do cursor, codificando uma seleção de "dual" e os cabeçalhos de dados e colunas estão voltando bem.

Então...

Lição 1) Se você receber um erro "a operação não será válida devido ao estado atual do objeto", sua conexão está fechada ou não há linhas de dados que estão sendo retornadas.

Lição 2) Não confie em seus escritores de procedimentos (se você não estiver escrevendo o código do banco de dados). Reserve os 30 minutos para revisar o código deles, se você acha que seu código deve funcionar. Pode economizar uma dúzia de horas perdidas :).

Obrigado a todos.

Outras dicas

Passei quase pelo mesmo cenário ... O principal problema era que não havia linhas de dados sendo retornadas. Que pode ser verificado usando:

    if(reader.HasRows)

A outra coisa que resolveu meu problema foi o uso de

    reader.NextResult()

Para chegar ao próximo cursor devolvido (fora).

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top