将 SQL 数据库导出到 WinForm DataSet,然后使用 DataSet 导出到 MDB 数据库
本文关键字:DataSet 数据库 MDB 然后 WinForm SQL | 更新日期: 2023-09-27 18:35:29
我的应用程序是一个依赖于数据库的winform 应用程序。在应用程序启动时,它会连接到服务器上的 SQL 数据库,并将此信息放入数据集/数据表中。
如果由于某种原因无法访问服务器上的数据库,则应用程序具有内置故障转移,它将从本地数据库获取其信息。
如果在正常情况下,我启动它将从 sql 数据库中读取的工具,并且如果它已在服务器上更新(单独的代码段检查这一点),它应该确保本地数据库是最新的,这就是问题开始的地方。(见下文)
这部分工作正常,并作为上下文添加 - 这是我们连接到SQL数据库的地方
public static DataSet dtsTableContents;
public static DataTable CreateDatabaseSQLConnection()
{
try
{
string strSqlConnectionString = "Data Source=MyLocation;Initial Catalog=MyCatalog;User=MyUser;Password=MyPassword;";
SqlCommand scoCommand = new SqlCommand();
scoCommand.Connection = new SqlConnection(strSqlConnectionString);
scoCommand.Connection.Open();
string strQueryToTable = "SELECT * FROM " + strTableName;
dtsTableContents = new DataSet();
SqlCommand scmTableInformation = new SqlCommand(strQueryToTable, scnConnectionToDatabase);
SqlDataAdapter sdaTableInformation = new SqlDataAdapter(scmTableInformation);
scnConnectionToDatabase.Open();
sdaTableInformation.Fill(dtsTableContents, strTableName);
DataTable dttTableInformation = dtsTableContents.Tables[strTableName];
scnConnectionToDatabase.Close();
return dttTableInformation;
}
catch
{
return null;
}
}
此代码段是从我的本地数据库读取的故障转移方法的一部分...
这部分工作正常,并作为上下文添加 - 这是我们连接到 MDB 数据库的地方
public static DataTable CreateDatabaseConnection()
{
try
{
string ConnectionString = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=MyLocation;Persist Security Info=True;JET OLEDB:Database Password=MyPassword;"
odcConnection = new OleDbConnection(ConnectionString);
odcConnection.Open();
string strQueryToTable = "SELECT * FROM " + strTableName;
DataSet dtsTableContents = new DataSet();
OleDbCommand ocmTableInformation = new OleDbCommand(strQueryToTable, ocnConnectionToDatabase);
OleDbDataAdapter odaTableInformation = new OleDbDataAdapter(ocmTableInformation);
ocnConnectionToDatabase.Open();
odaTableInformation.Fill(dtsTableContents, strTableName);
DataTable dttTableInformation = dtsTableContents.Tables[strTableName];
ocnConnectionToDatabase.Close();
return dttTableInformation;
}
catch
{
return null;
}
}
从我的 CreateDatabaseSQLConnection() 我有一个数据集。此数据集经过验证,包含服务器数据库中的所有信息。现在我一直在谷歌上搜索,发现自己试图根据这篇文章使用此代码更新本地数据库:http://msdn.microsoft.com/en-us/library/system.data.common.dataadapter.update(v=vs.71).aspx
public static void UpdateLocalDatabase(string strTableName)
{
try
{
if (CreateDatabaseConnection() != null)
{
string strQueryToTable = "SELECT * FROM " + strTableName;
OleDbDataAdapter odaTableInformation = new OleDbDataAdapter();
odaTableInformation.SelectCommand = new OleDbCommand(strQueryToTable, odcConnection);
OleDbCommandBuilder ocbCommand = new OleDbCommandBuilder(odaTableInformation);
odcConnection.Open();
odaTableInformation.Update(dtsTableContents, strTableName);
odcConnection.Close();
}
}
catch { }
}
此代码段运行无错误,但似乎没有改变任何内容。此外,运行此步骤所需的时间需要几毫秒,我认为这需要更长的时间。
我正在使用从 SQL 连接获得的数据集,我正在尝试将此数据集写入我的本地数据库。
可能是因为这是来自 SQL 连接的数据集,并且我无法通过我的 OleDbAdapter 将其写入我的 mdb 连接,还是我只是在这里错过了显而易见的内容?
任何帮助,不胜感激。
谢谢
凯文
用于从外部数据库到内部备份的直接备份
我只是一直在弄乱sdf和基于服务器的sql数据库,它已经工作了。这绝不是成品,但对于一列,我已经让程序从外部数据库中读取,然后用大约 15 行代码直接写入本地.sdf
SqlConnection sqlCon = new SqlConnection( ExternalDatabaseConnectionString );
SqlCeConnection sqlCECon = new SqlCeConnection( BackUpConnectionString );
using ( sqlCon )
{
using ( sqlCECon )
{
sqlCon.Open( );
sqlCECon.Open( );
SqlCommand get = new SqlCommand( "Select * from [TableToRead]", sqlCon );
SqlCeCommand save = new SqlCeCommand( "Update [BackUpTable] set InfoColumn = @info where ID = @id", sqlCECon );
SqlDataReader reader = get.ExecuteReader( );
if ( reader.HasRows )
{
reader.Read( );
save.Parameters.AddWithValue("@id", reader.GetString(0));
save.Parameters.AddWithValue( "@info", reader.GetString( 1 ));
save.ExecuteNonQuery( );
}
}
}
对于数据库的一行,备份一列,它可以工作,我假设你会有某种自动递增的键,比如 ID?
我认为第一步是减少对static
方法和字段的依赖。
如果你查看你的UpdateLocalDatabase
方法,你会发现你正在传入该方法使用的strTableName
但是UpdateLocalDatabase
调用(CreateDatabaseConnection
)的方法引用了一个名为相同的不同全局静态变量。 两个strTableName
变量很可能包含不同的值,并且您没有看到它们不是同一个变量。
此外,您正在尝试写出dtsTableContents
UpdateLocalDatabase
的全局静态数据集,但是如果您随后查看CreateDatabaseConnection
它实际上创建了该变量的本地版本 - 同样,您有两个变量命名为相同的东西,其中一个是全局的,一个是局部的。
我怀疑dtsTableContents
的两个变量是问题所在。
同样,我的建议是不要有任何静态方法或变量,对于您在这里所做的工作,尽量不要使用任何全局变量。此外,重构和/或重命名您的方法以匹配它们实际执行的操作。
在无休止地尝试使用DataAdapter.Update(Method)之后,我放弃了。我决定使用 sdf 文件而不是 mdb。
如果需要更新数据库,请使用相同的连接字符串删除本地数据库,创建一个新数据库。然后,我遍历数据集中的表,从中读取列名和类型,并基于此创建表。
在此之后,我遍历我的数据集并插入我的数据集的内容,我用来自服务器的信息填充了这些内容。下面是代码,这只是"快速而肮脏"的概念证明,但它适用于我的场景。
public static void RemoveAndCreateLocalDb(string strLocalDbLocation)
{
try
{
if (File.Exists(strLocalDbLocation))
{
File.Delete(strLocalDbLocation);
}
SqlCeEngine sceEngine = new SqlCeEngine(@"Data Source= " + strLocalDbLocation + ";Persist Security Info=True;Password=MyPass");
sceEngine.CreateDatabase();
}
catch
{ }
}
public static void UpdateLocalDatabase(String strTableName, DataTable dttTable)
{
try
{
// Opening the Connection
sceConnection = CreateDatabaseSQLCEConnection();
sceConnection.Open();
// Creating tables in sdf file - checking headers and types and adding them to a query
StringBuilder stbSqlGetHeaders = new StringBuilder();
stbSqlGetHeaders.Append("create table " + strTableName + " (");
int z = 0;
foreach (DataColumn col in dttTable.Columns)
{
if (z != 0) stbSqlGetHeaders.Append(", "); ;
String strName = col.ColumnName;
String strType = col.DataType.ToString();
if (strType.Equals("")) throw new ArgumentException("DataType Empty");
if (strType.Equals("System.Int32")) strType = "int";
if (strType.Equals("System.String")) strType = "nvarchar (100)";
if (strType.Equals("System.Boolean")) strType = "nvarchar (15)";
if (strType.Equals("System.DateTime")) strType = "datetime";
if (strType.Equals("System.Byte[]")) strType = "nvarchar (100)";
stbSqlGetHeaders.Append(strName + " " + strType);
z++;
}
stbSqlGetHeaders.Append(" )");
SqlCeCommand sceCreateTableCommand;
string strCreateTableQuery = stbSqlGetHeaders.ToString();
sceCreateTableCommand = new SqlCeCommand(strCreateTableQuery, sceConnection);
sceCreateTableCommand.ExecuteNonQuery();
StringBuilder stbSqlQuery = new StringBuilder();
StringBuilder stbFields = new StringBuilder();
StringBuilder stbParameters = new StringBuilder();
stbSqlQuery.Append("insert into " + strTableName + " (");
foreach (DataColumn col in dttTable.Columns)
{
stbFields.Append(col.ColumnName);
stbParameters.Append("@" + col.ColumnName.ToLower());
if (col.ColumnName != dttTable.Columns[dttTable.Columns.Count - 1].ColumnName)
{
stbFields.Append(", ");
stbParameters.Append(", ");
}
}
stbSqlQuery.Append(stbFields.ToString() + ") ");
stbSqlQuery.Append("values (");
stbSqlQuery.Append(stbParameters.ToString() + ") ");
string strTotalRows = dttTable.Rows.Count.ToString();
foreach (DataRow row in dttTable.Rows)
{
SqlCeCommand sceInsertCommand = new SqlCeCommand(stbSqlQuery.ToString(), sceConnection);
foreach (DataColumn col in dttTable.Columns)
{
if (col.ColumnName.ToLower() == "ssma_timestamp")
{
sceInsertCommand.Parameters.AddWithValue("@" + col.ColumnName.ToLower(), "");
}
else
{
sceInsertCommand.Parameters.AddWithValue("@" + col.ColumnName.ToLower(), row[col.ColumnName]);
}
}
sceInsertCommand.ExecuteNonQuery();
}
}
catch { }
}