none
COMO CREAR UN PROCEDURE DE CONSULTA EN ORACLE 10G XE?

    Pregunta

  • HOLA A TODOS, POR FAVOR NECESITO AYUDA, MIREN NESESITO UTILISAR PROCEDURE EN ORACLE PERO SEGUN LA RESPUESTA ANTERIOR DEBO DE UTILIZAR UN CURSOR LA VERDAD ES QUE NO ENTENDI MUY BIEN ESA PARTE,
    PORQUE EN EL EJEMPLO QUE ME PROPORCIONA LEANDRO DICHO QUERY NO HACE NINGUN FILTRO NI RECIBE PARAMETROS DESDE C# COMO INDICA EL EJEMPLO DE ABAJO.

    SELECT Sa03codctas, sa03descrip
                    FROM SamCataCtas03
                    WHERE sa03tipo= :tipo and sa03grupo= :grupo

    COMO LES INDICABA EN PREGUNTAS ANTERIORES MI PROYECTO DEBE SER HECHO EN TRES CAPAS Y ES POR ESO QUE NECESITO UTILIZAR MAYOR CANTIDAD DE PROCEDURE O FUNCTIONS EN ORACLE.

    POR FAVOR BRINDENME SU AYUDA, RECUERDEN QUE SOY NOVATO EN ESTE TEMA DE ORACLE....
    martes, 29 de diciembre de 2009 18:31

Respuestas

Todas las respuestas

  • Hola Ma_Juca,

    Te recomiendo que te des un vistazo a este link http://www.devjoker.com/asp/ver_contenidos.aspx?co_contenido=52

    y revises un poco de sintaxis PL_SQL

    "Creo" que cualquier procedimiento de Oracle trabaja con cursoes,si revisas la sentencia verás como se define...

    Si la respuesta te ha sido util Marcala como Respuesta o Votala.
    Mi Blog: Jtorrecilla
    martes, 29 de diciembre de 2009 18:38
    Moderador
  • Hola Ma_Juca

    echale un ojo a este link http://support.microsoft.com/kb/322160/es el ejemplo es para VBasic.Net pero espero lo puedas traducir a C#... como se muestra en el ejemplo lo mejor es utilizar Packeg asi tendras tus store procedures y funciones mas organizadas y como tu mencionas hay que utilizar cursores ya que Oracle no devuelve un rango de registros simplemente con SELECT * FROM  como lo hace SQL Server.

    Saludos,
    martes, 29 de diciembre de 2009 19:07
    Moderador
  • POR SI ACASO NO CONOCES ALGO QUE ESTÉ EN C#, PARA QUE ME PASES ES LINK
    martes, 29 de diciembre de 2009 19:30
  • hola

    ten en cuenta que los procedure de Oracle son bastante diferentes a los de SQL Server

    en principio estos tienen un spec y un body
    en el priemro defines una especie de contrato del reporte, y en el body agregarias el codigo


    un ejemplo en el body podrias escribir algo como esto

    PROCEDURE GetCuentas(tipoParam number, grupoParam number, outputCursor OUT out_cursor) AS
    BEGIN

        open outputcursor for
            SELECT Sa03codctas, sa03descrip
            FROM SamCataCtas03
            WHERE sa03tipo = tipoParam and sa03grupo = grupoParam
                   
    END GetCuentas;


    y en el spec algo como esto:


    create or replace package TestPKG is

      TYPE out_cursor IS REF CURSOR;

       PROCEDURE GetCuentas(tipoParam number, grupoParam number, outputCursor OUT out_cursor);

    end TestPKG ;


    - lo ideal aqui es que tambien selecciones que tool usas para coenctarte a Oracle, yo uso PL-SQL Developer, que me permite editar los package y agregar los spec y body
    pero puedes usar alguna otra tool
    por medio de esta tool podrias compilar el package, jeje si aqui se compila


    - tambien te en cuata que hay un limite para los nombres, no pueden ser tan largo como quieras

    saludos
    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina
    martes, 29 de diciembre de 2009 19:33
  • LA VERDAD ES QUE NO ENTIENDO MUCHO ESTE EJEMPLO, POR SI ACASO NO TIENES ALGUN OTRO EJEMPLO QUE ME PUEDAS FACILITAR.
    martes, 29 de diciembre de 2009 19:36
  • COMO QUE YA VOY ENTENDIENDO EL TEMA MUCHAS GRACIAS, PERO NECESTIO UNA AYUDITA MAS.

    DESDE C# COMO LOS EJECUTO ...
    miércoles, 30 de diciembre de 2009 0:53
  • hola

    deberia ser muy similar como usas sql server

    OracleConnection

    como veras en el ejemplo estableces la conexion y luego el comando lo ejecutas

    saludos
    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina
    miércoles, 30 de diciembre de 2009 1:17
  •  

    HOLA,

    MIRA PARA HACER INSERCIONES O MODIFICACION ESTOY USANDO ESTE STORE PROCEDURE, ME IMAGINO QUE PARA LA CONSULTA TIENE QUE SER IGUAL O HAY QUE HACER ALGO MAS.

    CLARO ESTA QUE ME REFIERO AL ENVIO DE PARAMETROS Y AL HACER LA MENCION DEL PROCEDURE.



    public
    void modificar(Atributos.DatoSamCataCtas plancta)

    {

        actualizarCtas(plancta,

    "uspModificarCtas");

    }

     

    private void actualizarCtas(Atributos.DatoSamCataCtas plancta, string spPlan)

    {

     

        OracleConnection cn = new OracleConnection(ConexionBD.Cadena);

     

        OracleCommand cm = new OracleCommand(spPlan, cn);

        cm.CommandType =

    CommandType.StoredProcedure;

        cm.Parameters.AddWithValue(

    "codcta", plancta.Sa03codctas);

        cm.Parameters.AddWithValue(

    "descrip", plancta.Sa03descrip);

        cm.Parameters.AddWithValue(

    "grupo", plancta.Sa03grupo);

        cm.Parameters.AddWithValue(

    "tipo", plancta.Sa03tipo);

        cm.Parameters.AddWithValue(

    "nivel", plancta.Sa03nivel);

        cm.Connection.Open();

        cm.ExecuteNonQuery();

        cm.Connection.Close();

    }

    miércoles, 30 de diciembre de 2009 2:46
  • hola

    para realziar la lectura lo ahces igual que en el insert, solo que al moemnto de obtener los datos especificas el nombre del cursor


    IDataReader reader = database.ExecuteReader("outputCursor ");

    if (reader.Read())
    {
        TextBox1.Text = Convert.ToString(reader["Nombre"]);
        .
        .
    }



    en el ejemplo de mas arriba habia declarado el procedure de esta forma:

    PROCEDURE GetCuentas(tipoParam number, grupoParam number, outputCursor OUT out_cursor);


    en principio seria sola esa la diferencia


    saludos
    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina
    miércoles, 30 de diciembre de 2009 15:30
  • Hola Leandro, Gracias por el ejemplo brindado, pero al momento de ejecutar tengo un problema, se ejecuta normalmente el cursor o store procedure se compila normalmente, pero al momento de ejecutarlo desde c# en la linea de codigo

    .executereader(nombre del cursor)

    me genera un error en sobrecarga en argumento, no sé si sea de llamar igual al store procedure como en el insert del ejemplo anterior, por favor ayudame con este tema.

    Gracias anticipadas.

    martes, 05 de enero de 2010 20:07
  • Hola Ma_Juca, no es necesario que indiques .executeReader(nombre del cursor) con que hagas .executeReader tendría que funcionarte prueba y me cuentas.
    Si la respuesta te ha sido util Marcala como Respuesta o Votala.
    Mi Blog: Jtorrecilla
    martes, 05 de enero de 2010 20:13
    Moderador
  • hola


    creo que jtorrecilla esta en lo correcto, es que como estoy usando una libreria distinta, puede que tenga algunos otras sobrecargas que la estandar no tiene


    pero guiate por este link
    Recuperar datos mediante DataReader <!-- -->

    la seccion "Cursores REF CURSOR de Oracle"

    creo que puede resultarte interesante

    saludos
    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina
    miércoles, 06 de enero de 2010 0:57
  • la verdad es que el cursor y procedure compila normamente, pero no sé si es que estoy haciendo algo mal al llamarlo desde C#.

    me podrian indicar como debo de llamar al procedure.


       OracleConnection cn = new OracleConnection(ConexionBD.Cadena); 
      OracleCommand cm = new OracleCommand("procedure", cn); 
      cm.CommandType =
    CommandType.StoredProcedure; 
      cm.Parameters.AddWithValue(
    "codcta", plancta.Sa03codctas);

      cm.Connection.Open();
      
       OracleDataReader reader= cm.ExecuteReader();
       
       while(reader.read()!=null)
        {
             AsignaParametro=reader.getInt32(0);
              ""
              ""
              //los parametros que se desee asignar...
         }
      

       reader.close();

        cm.Connection.Close();

    los que necesito saber es que si hay algo que mejorar en este tema y si es que me pueden indicar como se puede comprobar si el procedure funciona.

    la verdad es que esto ha sido un verdadero reto para mi, porque en primer lugar soy muy novato en este tema...

    por favor su ayuda...

    miércoles, 06 de enero de 2010 15:53
  • hola

    podrias hacer algo asi

    using(OracleConnection cn = new OracleConnection(ConexionBD.Cadena))
    {
        OracleCommand cm = new OracleCommand("procedure", cn);
        cm.CommandType = CommandType.StoredProcedure;
       
        cm.Parameters.AddWithValue("codcta", plancta.Sa03codctas);

        cm.Connection.Open();

        OracleDataReader reader = cm.ExecuteReader();

        while(reader.read())
        {
            string AsignaParametro = Convert.ToString(reader["campo1"]);
            .
            .
            //aqui recuperas los campos que devuelve el procedure
        }
    }


    no son muchos los cambios pero por ahi ayuden
    como veras el reader solo se usa el metodo Read() sin el null

    y dentro del while recuperas los campos que se devuelven el el select del cursor del procedure

    te ne cuanta tambien el tipo de dato del parametro
    o sea si has definido como NUMBER a "codcta" en tu SP, asegurate que la propiedad plancta.Sa03codctas sea del tipo int, ya que el metodo AddWithValue() toma el tipo de dato en base al tipo de dato del parametro que  se utiliza


    saludos
    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina
    miércoles, 06 de enero de 2010 16:32
  • Hola la respuesta de Leandro deberia de valerte. (la unica excepcion es el Read)

    te hago una pregunta, ¿Necesitas hacerlo con un reader? Me explico, que vas a hacer con dichos datos, los vas a utilizar mas tarde? vas a consultarlos nada mas...?

    Si la respuesta te ha sido util Marcala como Respuesta o Votala.
    Mi Blog: Jtorrecilla
    miércoles, 06 de enero de 2010 18:19
    Moderador
  • veras el profesosr que me di{o la induccion en la universidad me indico que no habia nada mas rapido en el datareader, entonces lo que quiero es hacer una consulta que puede ser reutilizada mas tarde.

    pero ya voy a tomo en cuenta las indicaciones que ud me hacen y lo pondre en practica.

    gracias por su ayuda...



    Mario Ayala J.
    miércoles, 06 de enero de 2010 18:29
  • Umh, te lo comento porque por ejemplo si vas a utilizar los datos de la aplicación quizas te resulte mejor tener los datos en un datatable,

    Con ello tu podras tener datos y manejarlos y luego volver a enviarlos a la Bd.

    el reader está muy bien, si unicamente vas a consultar, en el momento en el que vas a hacer alguna operacion con los datos, a mi personalmente, no me gustan.


    Si la respuesta te ha sido util Marcala como Respuesta o Votala.
    Mi Blog: Jtorrecilla
    miércoles, 06 de enero de 2010 18:40
    Moderador
  • hola

    en reaalidad te dio la mitad de la verdad, el datareader es rapido pero solo para acceso secuancial, yaq eu como tiene un cursosr contra la db es logico que le lectura sea rapida

    yo lo uso mucho en caso en dodne tengo que armar entidades de negocio, ya qeue s lo asm eprformante, pues ejecuto la query y mediante lectura secuancial armo las entidades


    ahora bien para manipular datos y poder filtrar en memoria, para poder transportarlos entre capas de tu desarrollo
    alli el reader no se peude usar

    por ejemplo quieres rapidamente hacer un servicio que seralice los datos y los envie a una aplicacion en la otra punta del mundo por internet
    que tipo de dato pasarias, jeej si lo mas rapido un dataset tipado, o uno simple

    pero ojo simpre hay otras tecnicas como usar el reader armar clases del tipo

    public class Producto
    {
       public int id {get; set;}
       public string Desc {get; set;}
    }


    y las cargas rapidamente con el reader y lo envias a le entidad de forma serialziada al servicio

    OracleDataReader

    Datareaders Vs DataSet ¿Porque tanta diferencia de tiempo en usar uno u otro método de acceso a datos?


    saludos
    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina
    miércoles, 06 de enero de 2010 18:44
  • HOLA,

    LA VERDAD ES QUE NO ME HA FUNCIONADO LOS EJEMPLOS QUE UD ME HAN FACILITADO



    PROCEDURE GetCuentas(tipoParam number,  outputCursor OUT out_cursor) AS
    BEGIN

        open outputcursor for
            SELECT Sa03codctas, sa03descrip
            FROM SamCataCtas03
            WHERE sa03tipo = tipoParam ;
                   
    END GetCuentas;


    create or replace package TestPKG is

      TYPE out_cursor IS REF CURSOR;

       PROCEDURE GetCuentas(tipoParam number, outputCursor OUT out_cursor);

    end TestPKG ;

    COMO VEN HE CREADO EXACTAMENTE COMO ESTÁ EN EL EJEMPLO,

    PERO LA LLAMADA DESDE C#.NET , NO SÉ SI ES QUE HAY QUE HACER ALGO DIFERENTE A LO QUE VEN MAS ABAJO.


        OracleConnection cn = new OracleConnection(ConexionBD.Cadena) 
        OracleCommand cm = new OracleCommand("procedure", cn);
        cm.CommandType = CommandType.StoredProcedure;
       
        cm.Parameters.AddWithValue("codcta", plancta.Sa03codctas);

        cm.Connection.Open();

        OracleDataReader reader = cm.ExecuteReader();

        while(reader.read())
        {
            string AsignaParametro = Convert.ToString(reader["campo1"]);
            .
            .
            //aqui recuperas los campos que devuelve el procedure
        }


    LA VERDAD ES QUE TENGO MUCHO DOLOR DE CABEZA CON ESTO Y ESTOY PENSANDO ALGO COMO CAMBIARME A SQL SERVER....

    ME DA MUCHA PENA TENER QUE VOTAR LA TOALLA COMO DICEN LOS BOXEADORES, PERP HAY QUE ACEPTAR CUANDO SE HA PERDIDO....

    viernes, 08 de enero de 2010 2:37
  • hola

    el codigo que posteas es el mismo que estas usando ?

    si es asi porque no pones el nombre del SP que has creado en el OledbCommand ?

    OracleCommand cm = new OracleCommand("GetCuentas ", cn);


    - ademas el paramtro es incorrecto de donde sales codcta ?

    no deberia ser:

    cm.Parameters.AddWithValue("tipoParam", plancta.Sa03codctas);


    dices que no funciona, pero obtienes algun error en particular?
    seria bueno que puedas poner la descripcion del error por lo general ayuda a detectar la causa del problema

    saludos
    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina
    viernes, 08 de enero de 2010 3:10
  • YO ME REFERIA A LA ESTRUCTURA, LA VERDAD ES QUE ESTOY UTILIZANDO DE LA MISMA FORMA COMO ME LO INDICAS


    OracleDataReader reader = cm.ExecuteReader();


    SE SALE ESTE ERROR

    ORA-06550: línea 1, columna 7:
    PLS-00201: el identificador 'USPCONSULTARCTA' se debe declarar
    ORA-06550: línea 1, columna 7:
    PL/SQL: Statement ignored

    CLARO ESTA QUE NO TIENE EL MISMO NOMBRE QUE EL DEL EJEMPLO PERO EL PROCEDIMIENTO ES EL MISMO...
     Y LA VERDAD ES QUE YA NO SE QUE HACER...
    viernes, 08 de enero de 2010 3:55
  • MIRA ESTE ES EL CURSOR REAL QUE ESTOY UTILIZANDO...


    create or replace PACKAGE curspkg_Cta AS
            TYPE Cta_cursor IS REF CURSOR ;
            Procedure uspConsultarCTA (codigo IN NUMBER, io_cursor OUT Cta_cursor);
       END curspkg_Cta

    create or replace PACKAGE BODY curspkg_Cta AS
       Procedure uspConsultar (codigo IN NUMBER, io_cursor OUT Cta_cursor)
       IS
            v_cursor Cta_cursor;
       BEGIN
     
                 OPEN io_cursor FOR
                 SELECT * FROM samcatactas03
                      WHERE sa03codctas =codigo;
            io_cursor:= v_cursor;
       END uspConsultarCta;
       END curspkg_Cta;


    ESTA ES LA APLICACION QUE ESTOY REALIZANDO EN C#.NET...


    public

    Atributos.DatoSamCataCtas ConsultaCtaAtrib(int codigo)
    {
          OracleConnection cn = new OracleConnection(ConexionBD.Cadena);
          OracleCommand cm = new OracleCommand("uspConsultarCta", cn);
          cm.CommandType = CommandType.StoredProcedure;
          cm.Parameters.AddWithValue(
    "codigo", codigo);
          cn.Open();
          OracleDataReader reader = cm.ExecuteReader();
          DatoSamCataCtas ctas = null;  //ESTA LINEA ESTOY INSTANCEANDO UNA CLASE DE ENTIDAD...
          while (reader.Read())
          {
                  ctas =
    new DatoSamCataCtas();
                  ctas.Sa03codctas = reader.GetInt32(0);
                  ctas.Sa03descrip = reader.GetString(1);
                  ctas.Sa03grupo = reader.GetString(2);
                  ctas.Sa03tipo = reader.GetString(3);
                  ctas.Sa03nivel = reader.GetInt32(4);
                  ctas.Sa03natural = reader.GetString(5);
                  //ctas.Sa03ctaanter = reader.GetInt32(6); 
          }
           reader.Close();
           cn.Close();
           return ctas;
    }


    POR FAVOR DIME QUE QUE TIPO DE ERROR ESTOY TENIENDO EN EL CODIGO, QUE HACE QUE NO ME FUNCIONE...

    viernes, 08 de enero de 2010 4:07
  • hola

    lo que veo que falta es que especifiques el package

    OracleCommand cm = new OracleCommand("curspkg_Cta .uspConsultarCta", cn);



    seguramente no analizaste estes ejemplo Recuperar datos mediante DataReader
    la seccion "Cursores REF CURSOR de Oracle"

    alli verias esto que te comento

    saludos
    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina
    viernes, 08 de enero de 2010 4:21
  • EL MISMO ERROR SE SUSCITA EN ESTA LINEA

    OracleDataReader reader = cm.ExecuteReader();

    ORA-06550: línea 1, columna 7:
    PLS-00905: el objeto PROYECTOSA.CURSPKG_CTA no es válido
    ORA-06550: línea 1, columna 7:
    PL/SQL: Statement ignored


    DONDE PROYECTOSA ES EL NOMBRE DE LA BASE DE DATOS...
    viernes, 08 de enero de 2010 4:26
  • hola LEANDRO TE CUENTO QUE YA PUDE HACER FUNCIONAR EL CURSOR EL PROBLEMA ERA QUE NO ESTABA PONIENDO ESTA LINEA DE CODIGO,

    cm.Parameters.Add(

    "io_cursor", OracleType.Cursor).Direction = ParameterDirection.Output;

    QUE ES PARA HACER LA REFERENCIA DEL CURSOR...
    AHORA BIEN, DE TODO CORAZON TE AGRADESCO MUCHO POR TU AYUDA.


    PERO NECESITO QUE ME AYUDES CON ALGO POR FAVOR, MIRA TAMBIEN ES NECESARIO QUE DESDE EL SISTEMA QUE ESTOY HACIENO PUEDA REALIZAR BACKUP'S Y A SU VEZ DIRECCIONAR EL ARCHIVO QUE SE GENERE DEL PROCESO DE RESPALDO...

    DE VERDAD MUY AGRADECIDO POR TU AYUDA...

    • Propuesto como respuesta Willyeruiz miércoles, 22 de febrero de 2012 20:42
    viernes, 08 de enero de 2010 5:23