3

我需要将数据从 SQL Server 2005 DB 导出到 Access 97 .mdb 文件。需要它的客户端需要它是 Access 97,因为他们将其导入的系统需要 Access 97 文件格式(不要让我开始)。有什么建议如何从 SQL 或 .Net(或 VB6 或 Ruby 或 Python ..)编写老式的 Access 文件?

提前谢谢,李

4

6 回答 6

4

我会让 Sql 2005 为你做这件事。

在 Sql Management Stuidio 中,右键单击源数据库,然后单击 Tasks,然后单击 Export Data。您可以使用它直接导出到您的 Access 数据库中,只需按照提示操作即可。或者,您可以将其输出为可用于放入 Access 的文件格式。

于 2009-07-23T16:16:16.127 回答
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 功能。当然,在这种情况下,您无论如何都不需要转换文件。

于 2009-07-29T19:07:56.903 回答
0

可能会给你一个起点。这篇文章有点老了,但你也许能学到一些东西。我只能找到那些使用与上一篇文章中的 Access 2000 兼容的 Jet 4.0 的人。使用 MS Access 驱动程序可能会给您想要的东西。

创建数据库后,使用 ADO.NET 中的常规 ODBC / OLE DB 相关内容创建表并使用您的数据填充它们。

于 2009-07-23T16:30:59.810 回答
0

这是一个很好的问题!我实际上希望能够以编程方式做这种事情,但在过去,我除了想出它之外什么都没有。然而,这些年来我的 .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();
}
于 2009-07-24T00:40:45.660 回答
0

最好的方法是通过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://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

于 2011-09-01T19:21:39.740 回答
-1

我认为从 SQL Server 执行此操作很疯狂。只需为您的 SQL Server 创建一个 ODBC DSN 并将表导入您的 Access 97 MDB 并完成它。您可能想要这样做的唯一原因是如果您想自动化它并重复执行它,但这也可以在 Access 中自动化(TransferDatabase 可以执行 ODBC 导入),并且只需要与那里一样多的代码行是要导入的表。

于 2009-07-23T18:32:49.940 回答