我需要编写一个 Access 97 .mdb 文件
Posted
技术标签:
【中文标题】我需要编写一个 Access 97 .mdb 文件【英文标题】:I need to write an Access 97 .mdb file 【发布时间】:2009-07-23 16:06:48 【问题描述】:我需要将数据从 SQL Server 2005 DB 导出到 Access 97 .mdb 文件。需要它的客户端需要它是 Access 97,因为他们将其导入的系统需要 Access 97 文件格式(不要让我开始)。有什么建议如何从 SQL 或 .Net(或 VB6 或 Ruby 或 Python ..)编写老式的 Access 文件?
提前致谢, 李
【问题讨论】:
我试图避免做这样的事情:support.microsoft.com/kb/237575 因为这是我需要自动化的事情。甚至不确定是否可以不这样做。 我已经对 Jet OleDb 3.51 驱动程序进行了 DL,并在注册表中注册了它们。当我尝试使用 3.51 驱动程序连接时,我得到“'Microsoft.Jet.OLEDB.3.51' 提供程序未在本地计算机上注册。” 【参考方案1】:我会让 Sql 2005 为你做这件事。
在 Sql Management Stuidio 中,右键单击源数据库,然后单击任务,然后单击导出数据。您可以使用它直接导出到您的 Access 数据库中,只需按照提示操作即可。或者,您可以将其输出为可用于放入 Access 的文件格式。
【讨论】:
这对于已安装的 Access 版本非常有用。不幸的是,写入旧版本的 Access 并没有帮助。随着 MDAC 2.1 的安装,Access 97 的驱动程序被 Access 2000 驱动程序覆盖。感谢所有的答案。【参考方案2】:您需要做的是将您安装的任何 Access 版本导出到 Access 文件中(只要它是 2000...2003;Access 2007 无法写入 Access 97 文件)。我假设您已经知道如何执行此操作。
然后您可以通过 COM 创建一个 Access 对象并要求它将您的新 .mdb 文件转换为新的 Access 97 数据库。在 VBScript 中,代码如下所示(如果您使用 VBA、VB.Net 或其他语言,请根据需要进行调整):
const acFileFormatAccess97 = 8
dim app
set app = CreateObject("Access.Application")
app.ConvertAccessProject "y:\mydatabase.mdb", "y:\mydatabase97.mdb", acFileFormatAccess97
如果您安装了 Access 97,上述命令将不起作用,因为该版本的 Access 没有 ConvertAccessProject 功能。当然,在这种情况下,您无论如何都不需要转换文件。
【讨论】:
【参考方案3】:This 可能会给你一个起点。 this article 有点老了,但你也许可以捡到一些东西。我只能找到那些使用与上一篇文章中的 Access 2000 兼容的 Jet 4.0 的人。使用 MS Access 驱动程序可能会给您想要的。
创建数据库后,使用 ADO.NET 中的常规 ODBC / OLE DB 相关内容创建表并使用您的数据填充它们。
【讨论】:
【参考方案4】:这是一个很好的问题!我实际上希望能够以编程方式做这种事情,但在过去,我除了想出它之外什么都没有。然而,这些年来我的 .NET 技能已经成熟了一点,我想我会尝试编写一个可以作为控制台应用程序执行的解决方案。这可以作为 windows server 或 sql server(使用 Sql Server 代理)上的计划任务来实现。我不明白为什么如果没有以下代码就不能从 Sql Server 自动执行此操作,但我真的很喜欢这个,所以我只需要把它放在那里。 Sql 和 Access 中的表都是狗的列表,带有 ID、名称、品种和颜色。通用的东西。这实际上适用于我的本地 Sql Server 实例和 Access 之间的桌面(2007,但我不知道为什么它不适用于 97)。欢迎批评指正。
顺便说一句,有以下几点:
using System.Data;
using System.Data.OleDb;
using System.Data.SqlClient;
这里:
static void Main(string[] args)
SqlConnectionStringBuilder cstrbuilder = new SqlConnectionStringBuilder();
cstrbuilder.DataSource = "localhost";
cstrbuilder.UserID = "frogmorton";
cstrbuilder.Password = "lillypad99";
cstrbuilder.InitialCatalog = "Dogs";
SqlConnection sconn = new SqlConnection(cstrbuilder.ToString());
sconn.Open();
SqlCommand scmd = new SqlCommand("select * from Dogs", sconn);
SqlDataReader reader = scmd.ExecuteReader();
if (reader.HasRows)
OleDbConnectionStringBuilder sb = new OleDbConnectionStringBuilder();
sb.Provider = "Microsoft.Jet.OLEDB.4.0";
sb.PersistSecurityInfo = false;
sb.DataSource = @"C:\A\StackOverflog\DogBase.mdb";
OleDbConnection conn = new OleDbConnection(sb.ToString());
conn.Open();
OleDbCommand cmd = new OleDbCommand("Delete from Dogs", conn);
cmd.CommandType = CommandType.Text;
cmd.ExecuteNonQuery();
conn.Close();
OleDbConnection conn2 = new OleDbConnection(sb.ToString());
conn2.Open();
OleDbCommand icmd = new OleDbCommand("Insert into dogs (DogID, DogName, Breed, Color) values (0, '1', '2', '3');", conn2);
icmd.CommandType = CommandType.Text;
while (reader.Read())
string insertCommandString =
String.Format("Insert into dogs (DogID, DogName, Breed, Color) values (0, '1', '2', '3');"
, reader.GetInt32(0)
, reader.GetString(1)
, reader.GetString(2)
, reader.GetString(3)
);
icmd.CommandText = insertCommandString;
icmd.ExecuteNonQuery();
conn2.Close();
sconn.Close();
【讨论】:
【参考方案5】:最好的方法是通过PInvoke 您需要将CREATE_DBV3
参数传递给SqlConfigDataSource()。这是我的 OSS 项目PlaneDisaster.NET 的JetSqlUtil.cs 中的代码:
#region PInvoke
private enum ODBC_Constants : int
ODBC_ADD_DSN = 1,
ODBC_CONFIG_DSN,
ODBC_REMOVE_DSN,
ODBC_ADD_SYS_DSN,
ODBC_CONFIG_SYS_DSN,
ODBC_REMOVE_SYS_DSN,
ODBC_REMOVE_DEFAULT_DSN,
private enum SQL_RETURN_CODE : int
SQL_ERROR = -1,
SQL_INVALID_HANDLE = -2,
SQL_SUCCESS = 0,
SQL_SUCCESS_WITH_INFO = 1,
SQL_STILL_EXECUTING = 2,
SQL_NEED_DATA = 99,
SQL_NO_DATA = 100
[DllImport("ODBCCP32.DLL",CharSet=CharSet.Unicode, SetLastError=true)]
private static extern int SQLConfigDataSource (int hwndParent, ODBC_Constants fRequest, string lpszDriver, string lpszAttributes);
[DllImport("ODBCCP32.DLL", CharSet = CharSet.Auto)]
private static extern SQL_RETURN_CODE SQLInstallerError(int iError, ref int pfErrorCode, StringBuilder lpszErrorMsg, int cbErrorMsgMax, ref int pcbErrorMsg);
#endregion
internal static string GetOdbcProviderName()
if (string.IsNullOrEmpty(OdbcProviderName))
var odbcRegKey = Registry.LocalMachine.OpenSubKey("SOFTWARE\\ODBC\\ODBCINST.INI\\ODBC Drivers", false);
var drivers = new List<string>(odbcRegKey.GetValueNames());
if (drivers.Contains("Microsoft Access Driver (*.mdb, *.accdb)"))
OdbcProviderName = "Microsoft Access Driver (*.mdb, *.accdb)";
else if (drivers.Contains("Microsoft Access Driver (*.mdb)"))
OdbcProviderName = "Microsoft Access Driver (*.mdb)";
else
//TODO: Condider checking for 32 versus 64 bit.
//TODO: Find a better exception type. http://***.com/questions/7221703/what-is-the-proper-exception-to-throw-if-an-odbc-driver-cannot-be-found
throw new InvalidOperationException("Cannot find an ODBC driver for Microsoft Access. Please download the Microsoft Access Database Engine 2010 Redistributable. http://www.microsoft.com/download/en/details.aspx?id=13255");
/// <summary>
/// Creates an Access 2003 database. If the filename specified exists it is
/// overwritten.
/// </summary>
/// <param name="fileName">The name of the databse to create.</param>
/// <param name="version">The version of the database to create.</param>
public static void CreateMDB (string fileName, AccessDbVersion version = AccessDbVersion.Access2003)
;
if (File.Exists(fileName))
File.Delete(fileName);
string command = "";
switch (version)
case AccessDbVersion.Access95:
command = "CREATE_DBV3";
break;
case AccessDbVersion.Access2000:
command = "CREATE_DBV4";
break;
case AccessDbVersion.Access2003:
command = "CREATE_DB";
break;
string attributes = String.Format("0=\"1\" General\0", command, fileName);
int retCode = SQLConfigDataSource
(0, ODBC_Constants.ODBC_ADD_DSN,
GetOdbcProviderName(), attributes);
if (retCode == 0)
int errorCode = 0 ;
int resizeErrorMesg = 0 ;
var sbError = new StringBuilder(512);
SQLInstallerError(1, ref errorCode, sbError, sbError.MaxCapacity, ref resizeErrorMesg);
throw new ApplicationException(string.Format("Cannot create file: 0. Error: 1", fileName, sbError));
如果您需要从 64 位版本的 SQL Server 执行此操作,则需要安装 64 位版本的 Office 2010 或 Microsoft Access Database Engine 2010 Redistributable。
【讨论】:
【参考方案6】:我认为从 SQL Server 执行此操作很疯狂。只需为您的 SQL Server 创建一个 ODBC DSN 并将表导入您的 Access 97 MDB 并完成它。您可能想要这样做的唯一原因是如果您想自动化它并重复执行它,但这也可以在 Access 中自动化(TransferDatabase 可以执行 ODBC 导入),并且只需要与那里一样多的代码行是要导入的表。
【讨论】:
从 SQL Server 执行此操作并不“疯狂”的一种情况是您没有 Access97 ;) 然后用你更高版本的 Access 创建一个 Access 97 数据库,导入数据,并将其转换为 97 格式。我建议从 2000 MDB(您可以在 Access 2000、2002、2003 和 2007 中创建)开始,导入数据并检查数据类型是否与 A97 兼容。任何与 97 不兼容的内容(例如 BYTE 字段),您都可以在转换之前更改为可以在 97 中使用的内容。以上是关于我需要编写一个 Access 97 .mdb 文件的主要内容,如果未能解决你的问题,请参考以下文章
Clear with query in database access 97 mdb c#