visual una studio reparar online mediante mdb gratis datos conexion conectar con como codigo cadena archivo abrir c# datatable dataadapter ms-jet-ace oledbconnection

una - C#Issue: ¿Cuál es la forma más sencilla de cargar un archivo.MDB, realizar cambios en él y guardar los cambios nuevamente en el archivo original?



mdb access (4)

¿Cómo te estás conectando a la base de datos (el archivo .mdb)? ¿Podría publicar un código de muestra? Si se está conectando a él correctamente, las operaciones de SQL que ejecute se deberían guardar automáticamente en la base de datos.

Entonces, después de conectarse a la base de datos, puede ejecutar SQL que creará tablas, insertará / actualizará / recuperará datos, etc. Intentar construir un archivo .mdb a mano no es aconsejable.

Aquí hay un ejemplo:

http://www.java2s.com/Code/CSharp/Database-ADO.net/Access.htm

Mi proyecto en el que estoy trabajando está casi terminado. Estoy cargando un archivo .MDB, mostrando los contenidos en un DataGrid e intentando obtener esos cambios en el DataGrid y guardarlos nuevamente en el archivo .MDB. También voy a crear una función que me permita tomar las tablas de un archivo .MDB y guardarlo en otro archivo .MDB. Por supuesto, no puedo hacer nada de esto si no puedo encontrar la forma de guardar los cambios en el archivo .MDB.

Investigué extensamente a Google y no hay respuestas a mi pregunta. Me considero un principiante en este tema específico, así que no hagas las respuestas demasiado complicadas. ¡Necesito la forma más sencilla de editar un archivo .MDB! Proporcione ejemplos de programación.

  1. Supongamos que ya he hecho una conexión a un DataGrid. ¿Cómo obtengo los cambios realizados por Datagrid? Estoy seguro de que este es lo suficientemente simple para responder.
  2. Entonces necesito saber cómo tomar esta tabla de datos, insertarla en el conjunto de datos de donde vino, tomar ese conjunto de datos y volver a escribir el archivo .MDB. (Si hay una forma de insertar solo las tablas que se cambiaron, lo preferiría).

Gracias de antemano, avíseme si necesita más información. Esto es lo último que probablemente tenga que preguntar sobre este tema ... gracias a Dios.

EDITAR:

El .mdb con el que estoy trabajando es una base de datos de Microsoft Access. (Ni siquiera sabía que había múltiples archivos .mdb)

Sé que no puedo escribir directamente en el archivo .MDB a través de un streamwriter o algo así, pero ¿hay alguna forma en la que posiblemente pueda generar un archivo .MDB con la información del DataSet ya incluida? O simplemente hay una manera en que puedo agregar tablas a un archivo .MDB que ya he cargado en DataGrid. ¡TIENE que haber una manera!

De nuevo, necesito una forma de hacer esto PROGRAMMATICAMENTE en C #.

EDITAR:

De acuerdo, mi proyecto es bastante grande, pero utilizo un archivo de clase separado para manejar todas las conexiones de la Base de datos. Sé que mi diseño y fuente son muy descuidados, pero hacen el trabajo bien. Solo soy tan bueno como los ejemplos que encuentro en internet.

Recuerde, simplemente me estoy conectando a un DataGrid en otra forma. Avíseme si quiere mi código del formulario Datagrid (no sé por qué lo necesitaría). DatabaseHandling.cs maneja 2 archivos .MDB. Entonces verás dos conjuntos de datos allí. Usaré esto eventualmente para tomar tablas de un Dataset y ponerlas en otro Dataset. Solo necesito averiguar cómo guardar estos valores BACK en un archivo .MDB.

¿Hay alguna forma de hacer esto? Tiene que haber una manera ...

EDITAR:

Por lo que he investigado y leído ... Creo que la respuesta está debajo de mis narices. Usando el comando "Actualizar ()". Ahora bien, aunque esto asegura que hay una manera simple de hacerlo, todavía me queda el problema de que no tengo idea de cómo usar este comando de actualización.

Tal vez puedo configurarlo de esta manera:

Oledb.OledbConnection cn = new Oledb.OledbConnection(); cn.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:/Staff.mdb"; Oledb.OledbCommand cmd = new Oledb.OledbCommand(cn); cmd.CommandText = "INSERT INTO Customers (FirstName, LastName) VALUES (@FirstName, @LastName)";

Creo que puede hacerlo, pero no quiero insertar nada manualmente. Quiero hacer ambas cosas en su lugar:

  • Tome la información que se modificó en la cuadrícula de datos y actualice el archivo de base de datos de Access (.mdb) de donde lo obtuve
  • Cree una función que me permita tomar tablas de otro archivo de base de datos de Access (.mdb) y reemplazarlas en un archivo de base de datos de Access secundario (.mdb). Ambos archivos usarán la misma estructura pero tendrán diferente información en ellos.

Espero que alguien encuentre una respuesta para esto ... mi proyecto está hecho, todo lo que le espera es una respuesta simple.

Gracias de nuevo por adelantado.

EDITAR:

De acuerdo ... buenas noticias. He descubierto cómo consultar el archivo .mdb en sí (creo). Aquí está el código, que no funciona porque recibo un error de tiempo de ejecución debido al comando sql que estoy intentando usar. Lo cual me llevará a mi próxima pregunta.

Nuevo código de función agregado a DatabaseHandling.cs:

static public void performSynchronization(string table, string tableTwoLocation) { OleDbCommand cmdCopyTables = new OleDbCommand("INSERT INTO" + table + "SELECT * FROM [MS Access;" + tableTwoLocation + ";].[" + table + "]"); // This query generates runtime error cmdCopyTables.Connection = dataconnectionA; dataconnectionA.Open(); cmdCopyTables.ExecuteNonQuery(); dataconnectionA.Close(); }

Como puede ver, he logrado ejecutar una consulta sobre la conexión en sí, que creo que es el archivo .MDB de acceso real. Sin embargo, como dije, la consulta SQL que he ejecutado en el archivo no funciona y generó un error en tiempo de ejecución cuando se usa.

Se supone que el comando que estoy intentando ejecutar debe tomar una tabla de un archivo .MDB y sobrescribir una tabla del mismo tipo de un archivo .MDB diferente. El comando SQL que intenté anteriormente intentó tomar directamente una tabla de un archivo .mdb y ponerla directamente en otro; esto no es lo que quiero hacer. Quiero tomar toda la información del archivo .MDB - poner las tablas en una tabla de datos y luego agregar todas las tablas de datos a un conjunto de datos (que he hecho). Quiero hacer esto para dos archivos .MDB. Una vez que tengo dos conjuntos de datos, quiero tomar tablas específicas de cada conjunto de datos y agregarlas a cada archivo como este:

  • DataSetA >>>> ----- [Agregar tablas (sobrescribirlas)] ----- >>>> DataSetB
  • DataSetB >>>> ----- [Agregar tablas (sobrescribirlas)] ----- >>>> DataSetA

Quiero tomar cada uno de esos conjuntos de datos y luego ponerlos de nuevo en cada archivo de acceso .MDB de donde vinieron. Esencialmente mantener ambas bases de datos sincronizadas.

Entonces mis preguntas, revisadas, son:

  1. ¿Cómo creo una consulta SQL que agregará una tabla al archivo .MDB sobrescribiendo el existente del mismo nombre? La consulta debería poder crearse dinámicamente durante el tiempo de ejecución con una matriz que reemplaza una variable con el nombre de la tabla que deseo agregar.
  2. ¿Cómo obtengo los cambios que realizó Datagrid en DataTable y los vuelvo a poner en una DataTable (o DataSet) para poder enviarlos al archivo .MDB?

Intenté elaborar lo más posible ... porque creo que no estoy explicando mi problema muy bien. Ahora esta pregunta ha crecido muchísimo demasiado. Solo desearía poder explicar esto mejor. : [

EDITAR:

Gracias a un usuario a continuación, creo que casi he encontrado una solución: la palabra clave casi . Aquí está mi código actualizado de DatabaseHandling.cs a continuación. Obtengo un error de tiempo de ejecución "Datatype Mismatch". No sé cómo podría ser posible teniendo en cuenta que estoy tratando de copiar estas tablas en otra base de datos con la misma configuración.

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Data.OleDb; using System.Data; using System.IO; namespace LCR_ShepherdStaffupdater_1._0 { public class DatabaseHandling { static DataTable datatableB = new DataTable(); static DataTable datatableA = new DataTable(); public static DataSet datasetA = new DataSet(); public static DataSet datasetB = new DataSet(); static OleDbDataAdapter adapterA = new OleDbDataAdapter(); static OleDbDataAdapter adapterB = new OleDbDataAdapter(); static string connectionstringA = "Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source=" + Settings.getfilelocationA(); static string connectionstringB = "Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source=" + Settings.getfilelocationB(); static OleDbConnection dataconnectionB = new OleDbConnection(connectionstringB); static OleDbConnection dataconnectionA = new OleDbConnection(connectionstringA); static DataTable tableListA; static DataTable tableListB; static public void addTableA(string table, bool addtoDataSet) { dataconnectionA.Open(); datatableA = new DataTable(table); try { OleDbCommand commandselectA = new OleDbCommand("SELECT * FROM [" + table + "]", dataconnectionA); adapterA.SelectCommand = commandselectA; adapterA.Fill(datatableA); } catch { Logging.updateLog("Error: Tried to get " + table + " from DataSetA. Table doesn''t exist!"); } if (addtoDataSet == true) { datasetA.Tables.Add(datatableA); Logging.updateLog("Added DataTableA: " + datatableA.TableName.ToString() + " Successfully!"); } dataconnectionA.Close(); } static public void addTableB(string table, bool addtoDataSet) { dataconnectionB.Open(); datatableB = new DataTable(table); try { OleDbCommand commandselectB = new OleDbCommand("SELECT * FROM [" + table + "]", dataconnectionB); adapterB.SelectCommand = commandselectB; adapterB.Fill(datatableB); } catch { Logging.updateLog("Error: Tried to get " + table + " from DataSetB. Table doesn''t exist!"); } if (addtoDataSet == true) { datasetB.Tables.Add(datatableB); Logging.updateLog("Added DataTableB: " + datatableB.TableName.ToString() + " Successfully!"); } dataconnectionB.Close(); } static public string[] getTablesA(string connectionString) { dataconnectionA.Open(); tableListA = dataconnectionA.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new Object[] { null, null, null, "TABLE" }); string[] stringTableListA = new string[tableListA.Rows.Count]; for (int i = 0; i < tableListA.Rows.Count; i++) { stringTableListA[i] = tableListA.Rows[i].ItemArray[2].ToString(); } dataconnectionA.Close(); return stringTableListA; } static public string[] getTablesB(string connectionString) { dataconnectionB.Open(); tableListB = dataconnectionB.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new Object[] { null, null, null, "TABLE" }); string[] stringTableListB = new string[tableListB.Rows.Count]; for (int i = 0; i < tableListB.Rows.Count; i++) { stringTableListB[i] = tableListB.Rows[i].ItemArray[2].ToString(); } dataconnectionB.Close(); return stringTableListB; } static public void createDataSet() { string[] tempA = getTablesA(connectionstringA); string[] tempB = getTablesB(connectionstringB); int percentage = 0; int maximum = (tempA.Length + tempB.Length); Logging.updateNotice("Loading Tables..."); for (int i = 0; i < tempA.Length ; i++) { if (!datasetA.Tables.Contains(tempA[i])) { addTableA(tempA[i], true); percentage++; Logging.loadStatus(percentage, maximum); } else { datasetA.Tables.Remove(tempA[i]); addTableA(tempA[i], true); percentage++; Logging.loadStatus(percentage, maximum); } } for (int i = 0; i < tempB.Length ; i++) { if (!datasetB.Tables.Contains(tempB[i])) { addTableB(tempB[i], true); percentage++; Logging.loadStatus(percentage, maximum); } else { datasetB.Tables.Remove(tempB[i]); addTableB(tempB[i], true); percentage++; Logging.loadStatus(percentage, maximum); } } } static public DataTable getDataTableA() { datatableA = datasetA.Tables[Settings.textA]; return datatableA; } static public DataTable getDataTableB() { datatableB = datasetB.Tables[Settings.textB]; return datatableB; } static public DataSet getDataSetA() { return datasetA; } static public DataSet getDataSetB() { return datasetB; } static public void InitiateCopyProcessA() { DataSet tablesA; tablesA = DatabaseHandling.getDataSetA(); foreach (DataTable table in tablesA.Tables) { CopyTable(table, connectionstringB); } } public static void CopyTable(DataTable table, string connectionStringB) { var connectionB = new OleDbConnection(connectionStringB); foreach (DataRow row in table.Rows) { InsertRow(row, table.Columns, table.TableName, connectionB); } } public static void InsertRow(DataRow row, DataColumnCollection columns, string table, OleDbConnection connection) { var columnNames = new List<string>(); var values = new List<string>(); for (int i = 0; i < columns.Count; i++) { columnNames.Add("[" + columns[i].ColumnName + "]"); values.Add("''" + row[i].ToString().Replace("''", "''''") + "''"); } string sql = string.Format("INSERT INTO {0} ({1}) VALUES ({2})", table, string.Join(", ", columnNames.ToArray()), string.Join(", ", values.ToArray()) ); ExecuteNonQuery(sql, connection); } public static void ExecuteNonQuery(string sql, OleDbConnection conn) { if (conn == null) throw new ArgumentNullException("conn"); ConnectionState prevState = ConnectionState.Closed; var command = new OleDbCommand(sql, conn); try { prevState = conn.State; if (prevState != ConnectionState.Open) conn.Open(); command.ExecuteNonQuery(); // !!! Runtime-Error: Data type mismatch in criteria expression. !!! } finally { if (conn.State != ConnectionState.Closed && prevState != ConnectionState.Open) conn.Close(); } } } }

¿Por qué recibo este error? Ambas tablas son exactamente lo mismo. ¿Qué estoy haciendo mal? En el peor de los casos, ¿cómo elimino la tabla en el otro archivo Access .MDB antes de insertar exactamente la misma tabla de estructura con diferentes valores en ella?

Hombre, desearía poder resolver esto ...

EDITAR:

De acuerdo, he venido a cierta distancia. Mi pregunta se transformó en una nueva, y por lo tanto, merece ser preguntado por separado. Me respondieron mi pregunta porque ahora sé cómo ejecutar consultas directamente a la conexión que abrí. ¡Gracias a todos!


En realidad, hay más de un formato de archivo con la extensión .mdb. Entonces, si adivino el equivocado, esta será la respuesta incorrecta. Pero suena como un problema de Microsoft Access.

No escribe directamente en un archivo MDB. Están encriptados y comprimidos. La forma más fácil de modificar un archivo MDB es cargarlo a través de Access y copiar las tablas a través de los métodos provistos.


No estoy seguro de lo lejos que has llegado, pero si buscas una operación rápida de arrastrar y soltar, tal vez quieras considerar la creación de un conjunto de datos fuertemente tipado que se conecte y las funciones de arrastrar y soltar de la ventana de la herramienta DataSources en Visual Studio.

Definitivamente hay muestras por ahí, pero querrás.

  1. Crear un nuevo DataSet
  2. Arrastrar y soltar desde su árbol de DataConnection en Server Explorer
  3. Crea un nuevo formulario
  4. Arrastra la tabla desde la herramienta DataSources
  5. Ventana a la forma.
  6. voila

Actualizar:

En primer lugar, no estoy al 100% de que entiendo tu problema. Si puede crear algunas tablas de enlaces entre los archivos de acceso que serían las mejores, entonces puede copiar los datos entre archivos utilizando una instrucción sql como ''INSERT INTO Customers SELECT FirstName, LastName FROM File2.Customers''. Si eso no es así, y la opción, creo que va a tener que hacer un bucle en las tablas de datos e insertar los registros manualmente usando instrucciones INSERT similares a su última edición. En cuanto a la cuadrícula de datos, probablemente tendrá que hacer un seguimiento de lo que cambió al monitorear el evento RowChanged (no estoy seguro si ese es el evento exacto) de incluso hacer las instrucciones de inserción / actualización cuando la fila cambie.

Actualizar:

para recorrer la tabla de datos, harías algo como esto. no probado. Acabo de actualizar esto de nuevo para incluir la función MakeValueDbReady. Esto tampoco se ha probado y no estoy seguro de haber manejado todos los casos o incluso todos los casos correctamente. Realmente tendrá que depurar la declaración sql y asegurarse de que está generando el valor correcto. Cada base de datos maneja los valores de manera diferente. Al menos de esta manera, el análisis de valor se extrae. También me di cuenta de que en lugar de codificar duro el TableName, debería poder obtenerlo de una propiedad en la DataTable

void CopyTable(DataTable table, string connectionStringB) { var connectionB = new OleDbConnection(connectionStringB); foreach(DataRow row in table.Rows) { InsertRow(row, table.Columns, table.TableName, connectionB); } } public static void InsertRow(DataRow row, DataColumnCollection columns, string table, OleDbConnection connection) { var columnNames = new List<string>(); var values = new List<string>(); // generate the column and value names from the datacolumns for(int i =0;i<columns.Count; i++) { columnNames.Add("[" + columns[i].ColumnName + "]"); // datatype mismatch should be fixed by this function values.Add(MakeValueDbReady(row[i], columns[i].DataType)); } // create the sql string sql = string.Format("INSERT INTO {0} ({1}) VALUES ({2})", table, string.Join(", ", columnNames.ToArray()), string.Join(", ", values.ToArray()) ); // debug the accuracy of the sql here and even copy into // a new Query in Access to test ExecuteNonQuery(sql, connection); } // as the name says we are going to check the datatype and format the value // in the sql string based on the type that the database is expecting public string MakeValueDbReady(object value, Type dataType) { if (value == null) return null; if (dataType == typeof(string)) { return "''" + value.ToString().Replace("''", "''''") + "''" } else if (dataType == typeof(DateTime)) { return "#" + ((DateTime)value).ToString + "#" } else if (dataType == typeof(bool)) { return ((bool)value) ? "1" : "0"; } return value.ToString(); } public static void ExecuteNonQuery(string sql, OleDbConnection conn) { if (conn == null) throw new ArgumentNullException("conn"); ConnectionState prevState = ConnectionState.Closed; var command = new OleDbCommand(sql, conn); try { // the reason we are checking the prev state is for performance reasons // later you might want to open the connection once for the a batch // of say 500 rows or even wrap your connection in a transaction. // we don''t want to open and close 500 connections prevState = conn.State; if (prevState != ConnectionState.Open) conn.Open(); command.ExecuteNonQuery(); } finally { if (conn.State != ConnectionState.Closed && prevState != ConnectionState.Open) conn.Close(); } }


Para actualizar el archivo MDB original con los cambios realizados en el DataSet (no en el DataGrid, ya que eso es solo UI sobre el DataSet) simplemente use el comando DataAdapter.Update .

Mover las tablas de 1 a la otra es un poco más complicado. Si la tabla aún no existe en el destino, deberá crearla usando una declaración SQL CREATE . Luego, DataAdapter . Completa un DataSet de la fuente . Pasa por cada fila y establece su estado en RowAdded llamando a DataRow.SetAdded . Luego, vuelva a pasarlo a DataAdapter.Update desde la base de datos de destino .

EDITAR: El código está en la siguiente pregunta ...