none
Hola buenas! ayuda, quiero conectar 3 bd y resumirlas en una sola! RRS feed

  • Pregunta

  • Hola grupo, tengo una practica en la universidad, resulta que el maestro nos hizo crear una bd y conectar con sql, mysql y postgres, en fin todas las cadenas de conexion van bien, pues en el web forms agregamos un boton y grid view. esto se hizo para cada manejador, es decir tenemos 3 botones y 3 grid view, cada uno conectado a un manejador distinto, solo al presionar el boton se muestran datos en el grid view, el maestro pidió resumir la info de los 3 manejadores en un solo boton y que se mostrara la info de las 3 bd en un solo gridview, pues basicamente es la misma bd en los 3 manejadores solo cambia la info se puede decir que haremos una union de todos los datos y el inventario en existencia de los productos, se sumaran.

    Dejo codigo de la conexion con MySql

    MySqlConnection conn = new MySqlConnection (@"Cadena de conexion");
          MySqlDataAdapter da  = new  MySqlDataAdapter();
          MySqlCommand cmd;
          DataTable data = new DataTable();
          cmd = new MySqlCommand ("Instruccion MySql", conn);
          cmd.Parameters.Add ("status", SqlDbType.NChar).Value = "n";
          da.SelectCommand = cmd;
          da.Fill(Data);
          DataGrid2.DataSource = data;
          DataGrid2.DataBind();

    Les agradezco!


    viernes, 8 de febrero de 2019 3:34

Respuestas

  • Veo que el que te repite es "Carretilla" en un caso y "carretilla" en el otro. Desde su punto de vista son dos productos distintos porque uno está en mayúsculas y otro en minúsculas.

    Esto es un problema que te encontrarás a menudo cuando escribas programas informáticos: a veces la definición de lo que hay que hacer no es suficientemente completa. No basta con decir "... hay que sumar los inventarios cuando dos productos sean iguales". Se necesita especificar qué se entiende por "ser iguales". En este caso concreto hay que despreciar mayúsculas y minúsculas y considerarlas iguales, pero en otros casos te encontrarás otras reglas tales como "despreciar los espacios en blanco" o "despreciar las tildes sobre las vocales".

    A la hora de programar, esas reglas hay que meterlas en las comparaciones de strings. En nuestro ejemplo estábamos comparando con el símbolo "==":

    if (dr1["NomP"] as string == dr2["Nomp"] as string)

    pero esta comparación es sensible a mayúsculas y minúsculas. Hay varias formas de realizar comparaciones insensibles. Una de ellas es usando string.Compare y pasándole un parámetro opcional "true":

    if (string.Compare(dr1["NomP"] as string), dr2["NomP"] as string), true) ...


    viernes, 15 de febrero de 2019 6:43

Todas las respuestas

  • Puedes usar las tres conexiones, cada una con su dataadapter, y a la hora de llamar al Fill pasarle siempre el mismo DataTable data (es decir, hacer tres veces un Fill del mismo DataTable, en lugar de un DataTable nuevo cada vez). Esto hace que los registros se vayan añadiendo en el DataTable (de forma predeterminada el dataadapter no lo limpia antes de cargarlo, aunque existe una opción para que lo haga). Al final de las tres cargas el DataTable tendrá todos los datos de las tres bases de datos, y puedes vincularlo al Grid y se verán juntos todos los registros.
    viernes, 8 de febrero de 2019 7:08
  • Hola, mas o menos entiendo, ahora se supone que en cada bd hay un producto que se repite el precio se mantiene y la existencia del producto varia obviamente en cada bd, se mostraran todos los productos en el grid y el que hay en cada bd se muestra solo una vez y el inventario se sumara quedando la existencia total de las 3 bds. 

    FCO. BALFRED

    domingo, 10 de febrero de 2019 4:43
  • Es una lastima que las tres bases de datos estén en tres servidores distintos. Si las tres estuviesen en un SQL Server sería sencillísimo porque simplemente harías un UNION de las tras selects y luego un GROUP BY del resultado de la select, y eso arrojaría directamente el resultado que buscas, y lo podrías cargar de una vez con un único "da.Fill".

    Pero si lo haces cargando tres veces el dataset con tres llamadas a las tras bases de datos, entonces el dataset contendrá tres veces el producto, y tendrás que hacer "a posteriori" un proceso que examine el dataset buscando los duplicados y agregando el inventario. La forma más fácil de hacerlo, si es que te lo permiten, sería usando LINQ-to-Datasets y poniéndole el groupby en una sentencia linq. Si no puedes usar linq, entonces habría que usar un bucle que recorra el dataset y por cada producto busque si hay duplicados (esto es rápido si tienes una clave primaria sobre el producto, pero si no la tienes es más eficiente ordenar primero el dataset por ese campo y así los duplicados quedan consecutivos). Entonces sumas el inventario de los duplicados, lo metes en el primer registro, y borras los duplicados.

    domingo, 10 de febrero de 2019 8:07
  • Todavia no veo Linq, cabe mencionar que voy en primero de la uni =/ y estoy aprendiendo apenas!

    FCO. BALFRED

    domingo, 10 de febrero de 2019 18:57
  • Puedes orientarme con el código? ya intente como entendi pero no me da

    FCO. BALFRED

    lunes, 11 de febrero de 2019 1:44
  • Ponnos aquí lo que lleves hecho, o por lo menos la parte que "no da", y miramos a ver cuál puede ser el error.
    lunes, 11 de febrero de 2019 7:32
  • No puedo juntar las tres cadenas de conexión en un solo botón, no se como hacerlo, ya intente y nada.

    FCO. BALFRED

    martes, 12 de febrero de 2019 16:33
  • No puedo juntar las tres cadenas de conexión en un solo botón

    No, claro que no puedes. Cada cadena tiene que ir aparte y usarse con su propio dataadapter, no las puedes juntar. Lo que tienes que juntar en un solo boton es los tres bloques de codigo que tienes en los tres botones, completos con todas sus lineas, incluyendo las tres conexiones y los tres dataadapters (pero tendras que cambiarles los nombres a las variables porque sino te dira que estan repetidas). La parte que hay que juntar y que solo tiene que ocurrir una vez es la de

    DataTable data = new DataTable();

    y entonces los tres bloques de codigo que copiaste hacen todos da.Fill(data) usando el mismo "data" (pero no el mismo da, que sera da1 da2 y da3 al copiar los tres bloques).

    martes, 12 de febrero de 2019 16:47

  •            public partial class WebForm1 : System.Web.UI.Page
        {
            protected void Page_Load(object sender, EventArgs e)
            {

            }

            protected void Button1_Click(object sender, EventArgs e)
            {
                SqlConnection conn = new SqlConnection(@"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=C:\Users\emozi\source\repos\Base802\Base802\App_Data\Database1.mdf;Integrated Security=True");
                SqlDataAdapter da = new SqlDataAdapter();
                SqlCommand cmd;
                DataTable data = new DataTable();
                cmd = new SqlCommand("SELECT * FROM  Productos", conn);
                //cmd.Parameters.Add("status", SqlDbType.NChar).Value = "n";
                da.SelectCommand = cmd;
                da.Fill(data);
                GridView1.DataSource = data;
                GridView1.DataBind();

            }

            protected void Button2_Click(object sender, EventArgs e)
            {
                MySqlConnection conn = new MySqlConnection(@"Server=localhost;Database=bd802;Uid=root;Pwd=root;");
                MySqlDataAdapter da1 = new MySqlDataAdapter();
                MySqlCommand cmd1;
                DataTable data1 = new DataTable();
                cmd1 = new MySqlCommand("SELECT * FROM  Productos", conn);
                //cmd.Parameters.Add("status", SqlDbType.NChar).Value = "n";
                da1.SelectCommand = cmd1;
                da1.Fill(data1);
                GridView2.DataSource = data1;
                GridView2.DataBind();

            }

            protected void Button3_Click(object sender, EventArgs e)
            {
                NpgsqlConnection conn = new NpgsqlConnection(@"Server=localhost;port=5432;Database=base802;UserId=postgres;Password=root;");
                NpgsqlDataAdapter da2 = new NpgsqlDataAdapter();
                NpgsqlCommand cmd2;
                DataTable data2 = new DataTable();
                cmd2 = new NpgsqlCommand("SELECT * FROM  Productos", conn);
                //cmd.Parameters.Add("status", SqlDbType.NChar).Value = "n";
                da2.SelectCommand = cmd2;
                da2.Fill(data2);
                GridView3.DataSource = data2;
                GridView3.DataBind();
            }


            protected void Button4_Click(object sender, EventArgs e)
            {
                SqlConnection conn = new SqlConnection(@"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=C:\Users\emozi\source\repos\Base802\Base802\App_Data\Database1.mdf;Integrated Security=True");
                SqlDataAdapter da = new SqlDataAdapter();
                SqlCommand cmd;
                DataTable data = new DataTable();
                cmd = new SqlCommand("SELECT * FROM  Productos", conn);
                //cmd.Parameters.Add("status", SqlDbType.NChar).Value = "n";
                da.SelectCommand = cmd;
                da.Fill(data);
                GridView4.DataSource = data;
                GridView4.DataBind();

                MySqlConnection conn1 = new MySqlConnection(@"Server=localhost;Database=bd802;Uid=root;Pwd=root;");
                MySqlDataAdapter da1 = new MySqlDataAdapter();
                MySqlCommand cmd1;
                DataTable data1 = new DataTable();
                cmd1 = new MySqlCommand("SELECT * FROM  Productos", conn1);
                //cmd.Parameters.Add("status", SqlDbType.NChar).Value = "n";
                da1.SelectCommand = cmd1;
                da1.Fill(data1);
                GridView4.DataSource = data1;
                GridView4.DataBind();

                NpgsqlConnection conn2 = new NpgsqlConnection(@"Server=localhost;port=5432;Database=base802;UserId=postgres;Password=root;");
                NpgsqlDataAdapter da2 = new NpgsqlDataAdapter();
                NpgsqlCommand cmd2;
                DataTable data2 = new DataTable();
                cmd2 = new NpgsqlCommand("SELECT * FROM  Productos", conn2);
                //cmd.Parameters.Add("status", SqlDbType.NChar).Value = "n";
                da2.SelectCommand = cmd2;
                da2.Fill(data2);
                GridView4.DataSource = data2;
                GridView4.DataBind();

    COMO SE OBSERVA VAN LOS CODIGOS DE CADA BOTON PERO JUNTE LOS TRES CODIGOS EN EL 4 BOTON Y SOLO ME CARGA LA INFO DE LA TABLA 1 LO DEMAS NO, QUE ESTOY HACIENDO MAL?


    FCO. BALFRED

    miércoles, 13 de febrero de 2019 3:20
  •  QUE ESTOY HACIENDO MAL?

    Lo que estás haciendo mal es que no has hecho caso cuando te dije que había que renombrar las variables EXCEPTO la variable "data" que debía ser única. Pero has usado data1, data2 y data3 en lugar de usar solo "data" y declararla una sola vez como te dije.

                 DataTable data = new DataTable();
    
                 SqlConnection conn = new SqlConnection(@"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=C:\Users\emozi\source\repos\Base802\Base802\App_Data\Database1.mdf;Integrated Security=True");
                 SqlDataAdapter da = new SqlDataAdapter();
                 SqlCommand cmd;
                 cmd = new SqlCommand("SELECT * FROM  Productos", conn);
                 //cmd.Parameters.Add("status", SqlDbType.NChar).Value = "n";
                 da.SelectCommand = cmd;
                 da.Fill(data);
    
                 MySqlConnection conn1 = new MySqlConnection(@"Server=localhost;Database=bd802;Uid=root;Pwd=root;");
                 MySqlDataAdapter da1 = new MySqlDataAdapter();
                 MySqlCommand cmd1;
                 cmd1 = new MySqlCommand("SELECT * FROM  Productos", conn1);
                 //cmd.Parameters.Add("status", SqlDbType.NChar).Value = "n";
                 da1.SelectCommand = cmd1;
                 da1.Fill(data);
    
                 NpgsqlConnection conn2 = new NpgsqlConnection(@"Server=localhost;port=5432;Database=base802;UserId=postgres;Password=root;");
                 NpgsqlDataAdapter da2 = new NpgsqlDataAdapter();
                 NpgsqlCommand cmd2;
                 cmd2 = new NpgsqlCommand("SELECT * FROM  Productos", conn2);
                 //cmd.Parameters.Add("status", SqlDbType.NChar).Value = "n";
                 da2.SelectCommand = cmd2;
                 da2.Fill(data);
    
                 GridView4.DataSource = data;
                 GridView4.DataBind();
    

    miércoles, 13 de febrero de 2019 7:15
  • Llevo casi 4 meses desde que empece a programar, y me esta costando, ya me muestra la info completa

    id NomP Precio Existencias
    1 Carretilla 500 10
    2 Pala 150 15
    3 Pico 170 15
    4 Barreta 200 20
    1 Carretilla 500 15
    2 Desarmador 40 15
    3 Cincel 45 15
    4 Martillo 95 20
    5 Mochila 200 9
    1 carretilla 500 30
    2 marro 120 15
    3 segueta 145 15
    4 motor 700 20

    Ahora me tiene que quedar asi

    id NomP Precio Existencias
    1 Carretilla 500 35  
    2 Pala 150 15
    3 Pico 170 15
    4 Barreta 200 20

    5 Desarmador 40 15
    6 Cincel 45 15
    7 Martillo 95 20
    8 Mochila 200 9

    9 marro 120 15
    10 segueta 145 15
    11 motor 700 20

    Carretilla se sumarian y sin los espacios,me esta costando este ejercicio, gracias por la ayuda!!


    FCO. BALFRED

    miércoles, 13 de febrero de 2019 11:47
  • Ok, aqui va una sugerencia para acumular los duplicados. Suponiendo que ya tienes los registros en "data", puedes usar un bucle como el siguiente. Observa que va en "marcha atras" para que no se haga un lio al borrar los duplicados:

    for (int i=data.Rows.Count-1; i>=0; i--) { DataRow dr1 = data.Rows[i]; for (int j=0; j<i; j++) { DataRow dr2 = data[j]; if (dr1["NomP"] as string == dr2["Nomp"] as string) { dr2["Existencias"] = ((int)dr2["Existencias"]) + (int)dr1["Existencias"]; // OJO, si el tipo de campo no es int, cambiar el (int) por el tipo correcto data.Rows.RemoveAt(i);

    break; // importante } } }




    miércoles, 13 de febrero de 2019 15:19
  • E que parte iria el codigo? lo puse al final y nada

    FCO. BALFRED

    miércoles, 13 de febrero de 2019 15:46
  • Se supone que lo que quieres es cambiar los datos despues de haberlos traido de las bases de datos y antes de presentarlos en el grid.

    Por lo tanto, ese codigo que modifica los datos tiene que ir despues del ultimo Fill y antes de asignar el "data" al DataSource del Grid.

    miércoles, 13 de febrero de 2019 17:06
  •  da2.SelectCommand = cmd2;
                da2.Fill(data);
    
                for (int i = data.Rows.Count - 1; i >= 0; i--)
                {
                    DataRow dr1 = data.Rows[i];
                    for (int j = 0; j < i; j++)
                    {
                        DataRow dr2 = data [j];  //Aqui marca error dice [] o se puede aplicar a un datatable
                        if (dr1["NomP"] as string == dr2["Nomp"] as string) 
                            dr2["Existencias"] += (int)dr1["Existencias"]; //AQui marca error dice += o se puede aplicar a operandos object y int 
                            break; // importante
                        }
                    }
                }
    
                GridView4.DataSource = data;
                GridView4.DataBind();
    
               
            }  Asi lo habia hecho como dice pero resulta que marca error, puse en comentario los errores 

    FCO. BALFRED


    • Editado Fco.Balfred jueves, 14 de febrero de 2019 4:41
    jueves, 14 de febrero de 2019 2:18
  • EDITADO: Perdón, releyendo el mensaje que escribí al principio quizá parezca un poco "brusca" la respuesta. Tal vez debí haber sido más suave y parece como si estuviese a la defensiva. Si da esa sensación, por favor no hagas caso; pregunta lo que haga falta y lo resolveremos.

    Asi lo habia hecho como dice pero resulta que marca error, puse en comentario los errores

    Cuando alguien te pone en el foro un código "escrito de memoria" (ya que al no tener el programa y datos completos no lo pueden escribir "de verdad" y probarlo) es completamente lógico que contenga algunos pequeños errores evidentes y fáciles de corregir. Ese código escrito de memoria no se supone que sirva para "copiar y pegar" y que funcione a la primera sin cambiar ni una coma. La idea es que "sirva de inspiración" para darte una idea de cómo sería una posible forma de acometer la solución, y que a partir de ese ejemplo escribas el código correcto sobre el proyecto real.

    En este caso, veamos los dos errores que se producen:

    El primero se queja de DaraRow dr2 = data[j]. ¿Cuál s la manera correcta de sacar un datarow desde un DataTable? Pues sencillamente accediendo a su colección de Rows. Cosa que está hecha un poco más arriba en el mismo código en donde accede a data.Rows[i]. No tenías más que copiar eso mismo a la j. Es obvio que al teclearlo de memoria se omitió la palabra "Rows".

    Y el segundo error está en dr2["Existencias"] += (int)dr1["Existencias"];. De este me di cuenta poco tiempo después de enviar el mensaje y volví a editarlo y lo corregí. El problema es que dr2["Existencias"] devuelve un valor de tipo Object (aunque en realidad tenga un número entero), y el Object no permite aplicarle el += para incrementar su valor. La solución es cambiarlo por un "cast" como está hecho en la respuesta corregida. Una vez más, es difícil darse cuenta de esto cuando estás tecleando el código de memoria en el foro, pero no cuando estás tecleando tu propio código sobre el programa real, porque Visual Studio te lo señala sobre la marcha y te indica los tipos de los objetos directamente desde el editor.


    jueves, 14 de febrero de 2019 20:56
  • HOLA! DE HECHO ME DI CUENTA DESPUES QUE FALTABA EL ROW! GRACIAS TODO BIEN SOLO ME REPITE DE LA SIGUENTE MANERA


    id NomP Precio Existencias
    1 Carretilla 500 25
    2 Pala 150 15
    3 Pico 170 15
    4 Barreta 200 20
    2 Desarmador 40 15
    3 Cincel 45 15
    4 Martillo 95 20
    5 Mochila 200 9
    7 Sacapunta 2.5 100
    1 carretilla 500 30  //AQUI REPITE
    2 marro 120 15
    3 segueta 145 15
    4 motor 700 20

    DE HECHO SI HACE LA SUMATORIA ENTONCES VA BIEN, INTENTE DECLARANDO UNA VARIABLE MAS A UN DATAROW NO MARCA ERROR PERO NO HACE NADA!

    ME ESTA COSTANDO APRENDER, ES MI PRIMER CICLO DONDE EMPEZAMOS A PROGRAMAR, SON MEDIO EXIGENTES LOS MAESTROS, AQUI SOLO EXPLICARON COMO HACER LAS CONEXIONES EL CODIGO FUE TODO NUESTRO. BUSCANDO EN LA RED ENCONTRE, PERO HAY COSAS QUE NO ALCANZO A COMPRENDER DEL TODO, EN FIN AGRADEZCO EL APORTE QUE HAN DADO ESPERO A FINAL DE LA CARRERA SALIR PROGRAMANDO QUE ME GUSTA ES CHIDO ESTE AMBIENTE!!!

    id NomP Precio Existencias
    1 Carretilla 500 25
    2 Pala 150 15
    3 Pico 170 15
    4 Barreta 200 20
    2 Desarmador 40 15
    3 Cincel 45 15
    4 Martillo 95 20
    5 Mochila 200 9
    7 Sacapunta 2.5 100
    1 carretilla 500 30
    2 marro 120 15
    3 segueta 145 15
    4 motor 700 20

    FCO. BALFRED

    viernes, 15 de febrero de 2019 3:17
  • Veo que el que te repite es "Carretilla" en un caso y "carretilla" en el otro. Desde su punto de vista son dos productos distintos porque uno está en mayúsculas y otro en minúsculas.

    Esto es un problema que te encontrarás a menudo cuando escribas programas informáticos: a veces la definición de lo que hay que hacer no es suficientemente completa. No basta con decir "... hay que sumar los inventarios cuando dos productos sean iguales". Se necesita especificar qué se entiende por "ser iguales". En este caso concreto hay que despreciar mayúsculas y minúsculas y considerarlas iguales, pero en otros casos te encontrarás otras reglas tales como "despreciar los espacios en blanco" o "despreciar las tildes sobre las vocales".

    A la hora de programar, esas reglas hay que meterlas en las comparaciones de strings. En nuestro ejemplo estábamos comparando con el símbolo "==":

    if (dr1["NomP"] as string == dr2["Nomp"] as string)

    pero esta comparación es sensible a mayúsculas y minúsculas. Hay varias formas de realizar comparaciones insensibles. Una de ellas es usando string.Compare y pasándole un parámetro opcional "true":

    if (string.Compare(dr1["NomP"] as string), dr2["NomP"] as string), true) ...


    viernes, 15 de febrero de 2019 6:43