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.C# Problema: ¿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?
He investigado extensamente en 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.
- 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.
- 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 solamente 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.
EDIT:
El .mdb estoy trabajando con una base de datos Microsoft Access . (Ni siquiera sabía que había varios archivos .mdb)
Sé que no puedo escribir directamente en el archivo .MDB a través de un secuenciador de secuencias o algo así, pero ¿hay alguna manera de que pueda generar un archivo .MDB con la información del conjunto de datos? Ya en ella? 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!
Una vez más, necesito una manera de hacer esto mediante programación en C#.
EDIT:
bien, mi proyecto es bastante grande, pero yo uso un archivo de clase independiente para manejar todas las conexiones de 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 hacerlo? Tiene que haber una manera ...
EDIT:
Por lo que he investigado y leído ... Creo que la respuesta está justo debajo de la nariz. 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 pueda configurarlo de la siguiente 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 manualmente nada. Quiero hacer ambas cosas en su lugar:
- tomar la información que se cambia en la cuadrícula de datos y actualizar el archivo de base de Access (.mdb) que yo tengo de
- Crear una función que me permite tomar las tablas desde otro archivo de base de datos de acceso (.mdb) y reemplazarlos en un archivo de base de datos de acceso 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 con antelación.
EDIT:
bien ... 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 añadida 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 se puede ver, de hecho he conseguido ejecutar una consulta en la conexión en sí, que creo que es el acceso real. Archivo MDB. 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 toma una tabla de un archivo .MDB y sobrescribe 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 que desee tomar las tablas específicas de cada conjunto de datos y añadirlos a cada archivo de la siguiente manera:
- DataSetA >>>> ----- [Agregar tablas (sobrescribir)] - ---- >>>> DataSetB
- DataSetB >>>> ----- [Agregar tablas (sobrescribir)] ----- >>>> DataSetA
quiero tomar esos 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.
Así que mis preguntas, revisada, es:
- ¿Cómo se crea una consulta SQL que añadirá una tabla en el archivo MDB al sobrescribir 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.
- ¿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?
He tratado de 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. : [
EDIT:
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é me aparece este error? Ambas tablas son exactamente lo mismo. ¿Qué estoy haciendo mal? Peor caso, ¿cómo elimino la tabla en el otro archivo .MDB de Access antes de insertar exactamente la misma tabla de estructura con diferentes valores en ella?
hombre que desearía poder resolver esto ...
EDIT:
bien, he llegado 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!
@Remou: tratando de llamar su atención aquí - usted está haciendo una mala situación peor. Acceso! = MDB. Todas estas preguntas que está volviendo a etiquetar de MDB a MS-ACCESS no implican acceso en absoluto, sino solo el motor de base de datos Jet/ACE. Estoy volviendo a etiquetar en consecuencia. –
@Remou @David W. Fenton: He planteado este problema en meta: http://meta.stackoverflow.com/questions/33216/ms-access-or-mdb-or-access-database-engine-or- ms-jet-ace – onedaywhen
Ya publiqué en Meta. MDB también es igual a los beans controlados por mensajes, por lo que es una etiqueta ambigua, y al igual que Access, que está etiquetado como ms-access debido a la ambigüedad, debe cambiar. – Fionnuala