Procesar MySQL dentro de lenguaje C

Colapsar
X
  • Filtrar
  • Tiempo
  • Mostrar
Limpiar todos
nuevos mensajes

  • Procesar MySQL dentro de lenguaje C

    Hola amigos,

    Estoy desarrollando una aplicación en lenguaje C, (entorno CentOS 6.3) y debo realizar rutinas que luego voy a automatizar con CRONs para que cada x minutos se ejecuten.

    El problema es que con mis pocos conocimientos de C se me esta complicando la lectura de los campos de la base.

    He logrado leer la base de MySQL pero tengo problemas con los TIPOS de DATOS

    mi código es este

    Código:
      res= mysql_use_result(conn);
      row= mysql_fetch_row(res);
    
      Fecha=row[0];
      Caja_Efectivo = row[1];
    
      printf("%d\n", row[1]);
    Row[1] trae un campo DECIMAL, 10,2

    Pero no he logrado mostrarlo ni capturarlo como tal..

    Lo malo es que tengo que tomarlo correctamente, porque es la base para otro SQL que tengo que armar..

    Espero que puedan ayudarme

    Gracias
    Pablo Tilotta
    Administrador
    www.vb-mundo.com
    www.juegosfl.com

  • #2
    Pues yo de C no sé ni por qué se denomina así... Pero, sólo por lógica, yo te animaría a que probaras con
    Código:
     
     Caja_Efectivo = Format(row[1],"######0.00")
    José María Movilla Cuadrado
    ______________________
    Normas del foro
    www.foro.vb-mundo.com
    www.vb-mundo.com

    Comentario


    • #3
      Cómo tienes declarado Caja_Efectivo?

      Se trata del compilador C de RedHat ?

      Prueba eb todo caso hacer un typecast a tipo double

      double Caja_Efectivo = (double)row[1];

      Sin más código del que pones no se me ocurre nada más.
      Un cordial saludo
      -Acalanto-

      Madrid - España

      Leer detalladamente las normas del foro es una buena forma de comenzar a participar en él. Te llevará unos pocos minutos y el colectivo de usuarios te lo agradecerá. <si no las has leído sigue este enlace>

      Comentario


      • #4
        Otra duda: ¿Estás seguro que 'res' tiene resultados correctos de la consulta realizada ?

        prueba a poner un bucle de lectura

        while (row = mysql_fetch_row(conn)) {
        double valor = (double)row[1];
        printf("%d\n", valor);
        }

        Otra posibilidad es que el propio motor de MySql te haga el typecast de las columnas del registro, algo parecido a como se ejecuta en SqLite y otras bases de datos

        double valor = row[1].getDouble();

        No se me ocurre nada más por el momento.
        Un cordial saludo
        -Acalanto-

        Madrid - España

        Leer detalladamente las normas del foro es una buena forma de comenzar a participar en él. Te llevará unos pocos minutos y el colectivo de usuarios te lo agradecerá. <si no las has leído sigue este enlace>

        Comentario


        • #5
          No amigo.. en C nada que ver con Format ni Visual Basic.

          Abrazo
          Pablo Tilotta
          Administrador
          www.vb-mundo.com
          www.juegosfl.com

          Comentario


          • #6
            Amigo Leonardo,.

            El código completo es este

            Código:
            /* librerías que usaremos */
            #include <mysql.h>
            #include <stdio.h>
            #include <stdlib.h>
            #include <time.h>
            
            int main()
            {
                    int  x;
                    /* Campos de Tabla Caja */
             
                    char *Fecha= "";
                    char *Caja_Efectivo="0";
                    char *Caja_EfectivoAnt="0";
                    char *Caja_RetirosContado="0";
                    char *Caja_VtaEfectivo="0";
                    char *Caja_CobranzasCtaCte="0";
                    char *Caja_Gastos="0";
                    char *Caja_Dolares="0";
                    char *Caja_CotizDolar="0";
                    char *Caja_Cheques="0";
                    char *Caja_CantCheques="0";
                    char *Caja_Visa="0";
                    char *Caja_VisaCuotas="0";
                    char *Caja_VisaDebito="0";
                    char *Caja_Mastercard="0";
                    char *Caja_MastercardCuotas="0";
                    char *Caja_Maestro="0";
                    char *Caja_Naranja="0";
                    char *Caja_Nativa="0";
                    char *Caja_CabalDebito="0";
                    char *Caja_FinanCuyo="0";
                    char *Caja_ValesCobrados="0";
                    char *Caja_ValesOtorgados="0";
                    char *Caja_CobranzaDeposito="0";
                    char *Caja_FactA_Inicial="0";
                    char *Caja_FactA_Final="0";
                    char *Caja_FactB_Inicial="0";
                    char *Caja_FactB_Final="0";
                    char *Caja_NCA_Inicial="0";
                    char *Caja_NCA_Final="0";
                    char *Caja_NCB_Inicial="0";
                    char *Caja_NCB_Final="0";
                    char *Caja_Presup_Inicial="0";
                    char *Caja_Presup_Final="0";
                    char *Caja_BN_Inicial="0";
                    char *Caja_BN_Final="0";
                    char *Caja_HoraApertura="0";
                    char *Caja_HoraCierre="0";
                    char *Caja_UtilidadContado="0";
                    char *Caja_UtilidadCtaCte="0";
                    char *Caja_TotalVtaContado="0";
                    char *Caja_CantVtaContado="0";
                    char *Caja_TotalVtaCtaCte="0";
                    char *Caja_CantVtaCtaCte="0";
                    char *Caja_EfectivoEntregado="0";
                    char *Caja_SubidoaWeb="0";
                    
                    /* Objetos para la Base ElectroMerlo Local */
                MYSQL *conn;
                MYSQL_RES *res;
                MYSQL_ROW row;
            
                    /* Objetos para la Base ElectroMerlo Web */
                    MYSQL *connW;
                MYSQL_RES *resW;
                MYSQL_ROW rowW;
             
                    /* Objetos para la Base ElectroMerlo Suc 02 */
                    MYSQL *conn02;
                MYSQL_RES *res02;
                MYSQL_ROW row02;
            
                    /* Datos de Conexión a MySQL Local */
                char *server = "192.168.10.2";
                char *user = "root";
                char *password = "eze2013";
                char *database = "electromerlo";
                conn = mysql_init(NULL);
            
                    /* Datos de Conexión a MySQL Web */
                char *serverW = "xxxxxxxx";
                char *userW = "xxxxxxxx";
                char *passwordW = "xxxxxxxx";
                char *databaseW = "web_electromerlo";
                connW = mysql_init(NULL);
            
                    /* Datos de Conexión a MySQL Suc 02 */
                char *server02 = "192.168.10.188";
                char *user02 = "root";
                char *password02 = "eze2013";
                char *database02 = "electromerlo";
                conn02 = mysql_init(NULL);
            
                /* conectar a la base de datos ElectroMerlo Local */
                if (!mysql_real_connect(conn, server, user, password, database, 0, NULL, 0))
                { /* definir los parámetros de la conexión antes establecidos */
                    fprintf(stderr, "%s\n", mysql_error(conn));
                    exit(1);
                }
            
                /* conectar a la base de datos ElectroMerlo Web */
                if (!mysql_real_connect(connW, serverW, userW, passwordW, databaseW, 0, NULL, 0))
                { /* definir los parámetros de la conexión antes establecidos */
                    fprintf(stderr, "%s\n", mysql_error(connW));
                    exit(1);
                }
            
                /* conectar a la base de datos ElectroMerlo Suc 02 */
                if (!mysql_real_connect(conn02, server02, user02, password02, database02, 0, NULL, 0))
                { /* definir los parámetros de la conexión antes establecidos */
                    fprintf(stderr, "%s\n", mysql_error(conn02));
                    exit(1);
                }
            
                /* Leo Ultima Fecha en Tabla em_caja01 */
            
                if (mysql_query(conn, "select max(Caja_Fecha) as Fecha FROM em_caja01"))
                {
                    fprintf(stderr, "%s\n", mysql_error(conn));
                    exit(1);
                }
            
                res = mysql_use_result(conn);
                row = mysql_fetch_row(res);
                
                    Fecha=row[0];
                    Caja_Efectivo=row[1];
                    Caja_EfectivoAnt=row[2];
                    Caja_RetirosContado=row[3];
                    Caja_VtaEfectivo=row[4];
                    Caja_CobranzasCtaCte=row[5];
                    Caja_Gastos=row[6];
                    Caja_Dolares=row[7];
                    Caja_CotizDolar=row[8];
                    Caja_Cheques=row[9];
                    Caja_CantCheques=row[10];
                    Caja_Visa=row[11];
                    Caja_VisaCuotas=row[12];
                    Caja_VisaDebito=row[13];
                    Caja_Mastercard=row[14];
                    Caja_MastercardCuotas=row[15];
                    Caja_Maestro=row[16];
                    Caja_Naranja=row[17];
                    Caja_Nativa=row[18];
                    Caja_CabalDebito=row[19];
                    Caja_FinanCuyo=row[20];
                    Caja_ValesCobrados=row[21];
                    Caja_ValesOtorgados=row[22];
                    Caja_CobranzaDeposito=row[23];
                    Caja_FactA_Inicial=row[24];
                    Caja_FactA_Final=row[25];
                    Caja_FactB_Inicial=row[26];
                    Caja_FactB_Final=row[27];
                    Caja_NCA_Inicial=row[28];
                    Caja_NCA_Final=row[29];
                    Caja_NCB_Inicial=row[30];
                    Caja_NCB_Final=row[31];
                    Caja_Presup_Inicial=row[32];
                    Caja_Presup_Final=row[33];
                    Caja_BN_Inicial=row[34];
                    Caja_BN_Final=row[35];
                    Caja_HoraApertura=row[36];
                    Caja_HoraCierre=row[37];
                    Caja_UtilidadContado=row[38];
                    Caja_UtilidadCtaCte=row[39];
                    Caja_TotalVtaContado=row[40];
                    Caja_CantVtaContado=row[41];
                    Caja_TotalVtaCtaCte=row[42];
                    Caja_CantVtaCtaCte=row[43];
                    Caja_EfectivoEntregado=row[44];
                    Caja_SubidoaWeb=row[45];
                   
                    printf( "%d\n", row[1] );
            
                /* se libera la variable res y se cierra la conexión */
                mysql_free_result(res);
                mysql_close(conn);
            }
            Si muestro por pantalla ROW[0] me lo muestra perfecto.. me muestra la Fecha del Registro.

            No se que versión de C es.. solo se que lo instale hace un par de días con el YUM -INSTALL
            Pablo Tilotta
            Administrador
            www.vb-mundo.com
            www.juegosfl.com

            Comentario


            • #7
              Espera..

              Tenia un error de concepto... por hacerlo a las apuradas

              ahora he cambiado esta linea para que me traiga todos los campos

              Código:
              if (mysql_query(conn, "select * FROM em_caja01 ORDER BY Caja_Fecha DESC LIMIT 1"))
              Cuando muestro por pantalla Caja_Efectivo me muestra 30962252 para un valor de 11663.75

              Pablo Tilotta
              Administrador
              www.vb-mundo.com
              www.juegosfl.com

              Comentario


              • #8
                En definitiva necesito de algun lenguaje para manejar MySQL que pueda compilarse y ejecutarse desde la Linea de Comando... no se si hacerlo en C, JAVA, PHYTON o en que...

                Ya me recomendaras tu que me conviene... tambien esta C++

                Que hago ? que me aconsejas ?
                Pablo Tilotta
                Administrador
                www.vb-mundo.com
                www.juegosfl.com

                Comentario


                • #9
                  Es muy raro.. ahora ejecuto esto

                  Código:
                  for (x=0; x<46; x++)
                          {
                             printf( "%s\n", row[x] );    
                          }
                  y funciona !!.. no entiendo nada.

                  Pablo Tilotta
                  Administrador
                  www.vb-mundo.com
                  www.juegosfl.com

                  Comentario


                  • #10
                    Claro: Fíjate bien que las variables sobre las que descargas el resultado de la consulta son PUNTEROS de tipo char, con lo que entiendo que en la tabla los campos estan definidos como VARCHAR aunque contengan un valor numérico.

                    Para recuperar el valor de la tabla utiliza Caja_Efectivo = &row[1] y cuando la muestres en pantalla hazlo con printf("%s\n", *Caja_Efectivo). La diferencia está en que CajaEfectivo te devolverá la dirección de memoria (puntero) en la que comienza la secuencia CHAR que contiene el valor y *CajaEfectivo el contenido que existe en esa dirección de memoria., es decir:

                    Caja_Efectivo devuelve 30962252 (Dirección de memoria que aloja el dato)
                    *Caja_Efectivo devuelve 11663.75 (Valor en formato char)

                    OJO QUE ESTÄS TRABAJANDO CON CHARS Y NO CON DATOS NUMËRICOS.

                    Cualquier plataforma es buena para desarrollar, pero para mayor comodidad yo utilizaría JAVA o CSharp. En este último te puedo ayudar con mayor conocimiento ya que con C++ no tengo mucha experiencia en desarrollo de interfaces con el usuario. Si tan solo se trata de realizar consultas a MySql, lo podemos hacer sin problemas salvo los que sean consecuencia de no disponer de las mismas herramientas y equipos.

                    Espero que te resulte útil.


                    PD: Edito porque no sé si me he explicado con suficiente claridad.

                    Vamos a ver, en C/C++ cuando declaras char *midato = "0"; C guarda ese carácter en una posición libre de memoria y esa dirección en el puntero midato.

                    Si inspeccionas midato el compilador te devolverá la dirección de memoria, si inspeccionas *midato te devolverá el caracter 0 caracteres que se encuentran en dicha posición, posición que para mayor INRI ocupa dos bytes ya que C inserta un caracter '\0' para determinar dónde finaliza la serie de caracteres, por ejemplo:

                    char *midato = "Hola Mundo";

                    midato contiene la dirección de memoria de midato de tipo char
                    *midato devuelve lo que existe en esa dirección de memoria hasta llegar al char '\0'.

                    Esto es así porque C no tiene por si mismo tipos cadena (string) y por lo tanto está obligado a crear punteros a caracteres para lograr trabajar con lo que otros lenguajes tratan como string. C++ de últimas generaciones ya incorporan clases de tipo String que evitan al programador tener que trabajar con punteros char.

                    Si como veo en el código estás declarando e instanciando con un carácter '0' un puntero tipo char para Caja_Efectivo, esta variable tendrá la dirección de memoria de ese '0'. Si le pasas el resultado de la consulta en forma

                    Caja_Efectivo = row[n]

                    lo que estás haciendo es poner como nueva dirección de memoria el contenido de row[n] y no el puntero que determina la posición de memoria de row[n], dicho de otra manera:

                    row[n] tiene el valor del registro qwue además entiendo que debe ser algún tipo numérico como por ejemplo 101256; si ese valor se lo traspasas al puntero Caja_Efectivo, ésta, ahora buscará en la posición de memoria 101256....y qwue cosa puede haber en esa posición.....!!Cualquier cosa menos 101256!!

                    &row[n] lo que nos devuelve es la posición de memoria (puntero) en el que se encuentra el contenido, por lo tanto se debe pasar el valor al puntero Caja_Efectivo como Caja_Efectivo = &row[n] que es el puntero y entonces *Caja_Efectivo nos devolvera el contenido del puntero, es decir, 101256.

                    No sé de que forma están definidos los campos de la tabla, pero creo que te ahorrarías muchos problemas con algo parecido a esto.

                    double Caja_Efectivo = row[1];

                    Un cordial saludo
                    -Acalanto-

                    Madrid - España

                    Leer detalladamente las normas del foro es una buena forma de comenzar a participar en él. Te llevará unos pocos minutos y el colectivo de usuarios te lo agradecerá. <si no las has leído sigue este enlace>

                    Comentario


                    • #11
                      Impecable amigo...

                      Definí Caja_Efectivo del tipo CHAR porque no tengo que hacer operaciones con el.. simplemente pense que así podia convertirlo en String.

                      El objetivo del programa es replicar ciertos datos de una Base Local, de un servidor local, en un servidor remoto (WEB)... y finalmente desarrollar una Aplicación para ANDROID que acceda a esa Base MySQL Web y despliegue en el movil los datos de Arqueo (cantidad de efectivo recaudado, venta del día, etc)

                      Y que debo hacer si quiero leer un valor DECIMAL de MySQL y convertirlo a VARCHAR o STRING ?

                      Saludos
                      Pablo Tilotta
                      Administrador
                      www.vb-mundo.com
                      www.juegosfl.com

                      Comentario


                      • #12
                        La transformación depende en gran medida de los encabezados que puedas incluir en el compilador c++ con el que trabajas, el cual supongo que se trata de c++ aunque sospecho que trabajas bajo linux ??

                        si lo deseas convertir a un puntero de tipo char como estabas declarando en el código, y suponiendo que la columna 1 de la tabla es un formato numérico de tipo double, entonces:

                        char* caja_efectivo = (char*)(&row[1]); /*Fíjate que no tomo el valor de row[1] sino la posición que ocupa en memoria con el casting de puntero '&' */

                        Si el compilador con el que trabajas dispone de clases tipo string, entonces puedes tratar de probar lo siguiente (Verifica que los includes existen con este mismo nombre que te pongo).

                        #include <iostream.h>
                        #include <string.h>
                        ...
                        ...
                        ...
                        std::string caja_efectivo = std::to_string(row[1]); /*Entiendo que row[1] en mysql está definido como tipo numérico con decimales*/

                        Aunque la normativa de C es bastante clara y todos los fabricantes la suelen respetar, no puedo garantizar que este código te funcione al 100% y que alguna clase pueda tener otro nombre en el entorno que estás trabajando.


                        Otra sugerencia pasa por comentarte que si lo que necesitas es ejecutar una sincronización entre las DB MySql locales y la existente en la web, lo puedes desarrollar desde VB6 sin ningún tipo de problema. Para ello descargas desde la página de MySql el driver ODBC de Mysql, instalas la aplicación en cada servidor local y estableces la conexión con éste y con la web (funciona perfectamente) y realizas la sincronización sin ningún tipo de problema.

                        Espero que te resulte útil todo este panegírico.

                        PD: Ahora caigo en que los servidores deben trabajar babo Linux pero puedes insttalar la aplicación VB6 en equipos windows que estén conectados a cada servidor local. Si esto no es posible...pues...adelante con C++ sin dejar de lado la posibilidad de hacerlo con Mono C#......programas en c# con VS 20xx, copias los ficheros y los ejecutas en linux con Mono y funciona a las mil maravillas, eso sí, evitando poner en la aplicación librerías privativas de Windows, es la única restricción que tiene Mono.

                        Un cordial saludo
                        -Acalanto-

                        Madrid - España

                        Leer detalladamente las normas del foro es una buena forma de comenzar a participar en él. Te llevará unos pocos minutos y el colectivo de usuarios te lo agradecerá. <si no las has leído sigue este enlace>

                        Comentario


                        • #13
                          Si amigo.. lo puedo hacer en VB 6.0 o en VB.NET, no hay problema con ello... pero lo que necesito es diferente..

                          Porque para que se ejecute un ejecutable de VB 6.0 o de VB.NET debo dejar una PC Corriendo las 24 hs y cuando nos retiramos de la oficina, solo el Servidor Linux CentOS 6.3 queda online.

                          Y de esa forma, si un día no voy a la oficina, alguien tendria que encender mi PC

                          La idea es aprovechar la potencia del lenguaje C... NO C++ y la estabilidad del Linux/Unix

                          Son procesos 100 % Batch.. no necesitan intervención del usuario.

                          Es por eso que necesito de la potencia del C.

                          Abrazo
                          Pablo Tilotta
                          Administrador
                          www.vb-mundo.com
                          www.juegosfl.com

                          Comentario


                          • #14
                            Pero entonces todo resulta mucho más sencillo y no tienes que complicarte transformando datos numéricos en cadena o viceversa, simplemente buscas los registros de la(s) bases locales que han sufrido alguna modificación o que son de nueva factura y los actualizas mediante INSERT TO...SELECT * FROM...etcétera.

                            Para ello una aplicación que se ejecuta en un bucle infinito y que actúa como un demonio en cada servidor local.

                            También puedes programar que las transacciones se ejecuten en horario nocturno, pero entonces la réplica no sería en tiempo real.

                            No sé si te he comprendido correctamente.
                            Un cordial saludo
                            -Acalanto-

                            Madrid - España

                            Leer detalladamente las normas del foro es una buena forma de comenzar a participar en él. Te llevará unos pocos minutos y el colectivo de usuarios te lo agradecerá. <si no las has leído sigue este enlace>

                            Comentario


                            • #15
                              Si, de hecho estoy pensando no mover los ROWS a variables... trabajar directamente con ellos ..

                              La idea es leer 2 bases MySQL... una local.. otra que esta en el servidor de la 2da sucursal, y con la info de ambos... replicar en el servidor Web.

                              Voy a avanzar y cualquier duda te consulto

                              Mil gracias amigo..
                              Pablo Tilotta
                              Administrador
                              www.vb-mundo.com
                              www.juegosfl.com

                              Comentario

                              Trabajando...
                              X