我需要编写一个 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#

在 Access 97 的 SQL 查询中访问另一个受密码保护的数据库

访问 97 个数据库

将 Access 数据库转换为 97 格式

Access数据库:能否编译mdb文件到exe文件?

无法使用 OLEDB 连接 MS Access(.mdb 文件)