【问题标题】:I need to write an Access 97 .mdb file我需要编写一个 Access 97 .mdb 文件
【发布时间】: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' 提供程序未在本地计算机上注册。”

标签: ms-access ms-access-97


【解决方案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.NETJetSqlUtil.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://stackoverflow.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 中使用的内容。
          猜你喜欢
          • 1970-01-01
          • 2019-05-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-02-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多