【问题标题】:How to determine Jet database Engine Type programmatically如何以编程方式确定 Jet 数据库引擎类型
【发布时间】:2023-03-10 16:41:02
【问题描述】:

我有一个程序需要将它打开的任何 Access (Jet) 数据库升级到 JET Version4.x,如果它还不是那个版本的话。 (这可以使用 SQL-92 语法特性)

升级(相对)容易。调用 JRO.JetEngine 对象的 CompactDatabase 方法 (as described here) 应该可以解决问题,但在此之前,我需要确定是否需要升级。如何确定现有数据库的 Jet OLEDB:Engine Type?这可以通过打开的 OleDBConnection 确定吗?

注意:

  1. 我说的是数据库版本,而不是 Jet 库版本。
  2. 非常感谢 C# 或 .Net 解决方案。
  3. 这是一个使用 Jet 引擎的应用程序,而不是 Access 应用程序。

【问题讨论】:

  • 不能从Connection对象中读取吗?
  • 您真的在更新 Access 97 或以前的数据库吗?从 Access 2000 开始的任何东西都将使用 Jet 4.0。
  • Jet 4 支持向后兼容 A97。也就是说,您可以使用 Jet 4 来更新 Jet 3.x 数据库——无需为此使用 Jet 3.x。
  • @scope-creep 连接对象似乎只返回了我用来打开连接的信息,而不是连接到的数据库的信息。
  • @Thomas - 目的是转换为 Access 2003(将版本标识为“旧”)。我认为它们是 2000 年创建的任何版本,但目前找不到 Access -> Jet 引擎类型的文档。

标签: c# .net ms-access jet


【解决方案1】:

我知道这是一篇旧帖子,但我已经寻找了几天来找到可以检索的其他属性列表,例如“Jet OLEDB:Engine Type”。这是列出所有属性的 MS 链接。 Jet Provider Specific Connection Parameters Listing

【讨论】:

    【解决方案2】:

    只需对使用 SQL-92 语言功能的语句进行测试调用。如果失败,则需要升级。

    【讨论】:

    • 如果我在回答自动被接受之前就已经到了这里,那么你就会打勾!测试某个功能的存在总比测试某个特定版本的存在要好。谢谢。
    • 但是答案是错误的,因为SQL 92是否失败的问题在于使用哪个版本的Jet来访问数据文件以及您使用的是哪个接口( ADO 使用 SQL 92,DAO 使用 SQL 89)。这完全独立于数据文件的版本。
    • @David-W-Fenton。我将不得不进一步调查。 Jet 驱动程序肯定比数据库更新,但在较旧的数据库上使用较新语法的 DDL 调用失败。顺便说一句,访问是通过 OLEDB 进行的,它大概等于 ADO。
    • 对,ADO 是 OLEDB 的封装,所以如果你使用它,你会使用所谓的 SQL92 语法。但重点是,这不会作为目标文件版本的测试,与访问它所涉及的数据接口 (ADO/DAO) 和 Jet/ACE 版本相反。
    【解决方案3】:

    您可以使用 Office Interop 并获取信息(公然从文章中窃取):

    How Can I Determine Which Version of Access was Used to Create a Database?

        public void WhichVersion(string mdbPath)
        {
            Microsoft.Office.Interop.Access.Application oAccess = new Microsoft.Office.Interop.Access.ApplicationClass();
            oAccess.OpenCurrentDatabase(mdbPath, false, "");
    
            Microsoft.Office.Interop.Access.AcFileFormat fileFormat = oAccess.CurrentProject.FileFormat;
    
            switch (fileFormat)
            {
                case Microsoft.Office.Interop.Access.AcFileFormat.acFileFormatAccess2:
                    Console.WriteLine("Microsoft Access 2"); break;
                case Microsoft.Office.Interop.Access.AcFileFormat.acFileFormatAccess95:
                    Console.WriteLine("Microsoft Access 95"); break;
                case Microsoft.Office.Interop.Access.AcFileFormat.acFileFormatAccess97:
                    Console.WriteLine("Microsoft Access 97"); break;
                case Microsoft.Office.Interop.Access.AcFileFormat.acFileFormatAccess2000:
                    Console.WriteLine("Microsoft Access 2000"); break;
                case Microsoft.Office.Interop.Access.AcFileFormat.acFileFormatAccess2002:
                    Console.WriteLine("Microsoft Access 2003"); break;
            }
    
            oAccess.Quit(Microsoft.Office.Interop.Access.AcQuitOption.acQuitSaveNone);
            Marshal.ReleaseComObject(oAccess);
            oAccess = null;
        }
    }
    

    编辑:

    另一种方法是使用 DAO(来自此 link 翻译自日语)。您可能需要调整这些值,但这看起来是个不错的起点。

    public int GetCreatedVersion(string mdbPath)
    {
        dao.DBEngine engine = new dao.DBEngine();
        dao.Database db = engine.OpenDatabase(mdbPath, false, false, "");
        string versionString = db.Properties["AccessVersion"].Value.ToString();
        int version = 0;
        int projVer = 0;
    
        switch (versionString.Substring(0, 2))
        {
            case "02":
                version = 2; break;
            case "06":
                version = 7; break;
            case "07":
                version = 8; break;
            case "08":
                foreach (dao.Property prop in db.Properties)
                {
                    if (prop.Name == "ProjVer")
                    {
                        projVer = int.Parse(prop.Value.ToString());
                        break;
                    }
                }
                switch (projVer)
                {
                    case 0:
                        version = 9; break;
                    case 24:
                        version = 10; break;
                    case 35:
                        version = 11; break;
                    default:
                        version = -1; break;                            
                }
                break;
            case "09":
                foreach (dao.Property prop in db.Properties)
                {
                    if (prop.Name == "ProjVer")
                    {
                        projVer = int.Parse(prop.Value.ToString());
                        break;
                    }
                }
                switch (projVer)
                {
                    case 0:
                        version = 10; break;
                    case 24:
                        version = 10; break;
                    case 35:
                        version = 11; break;
                    default:
                        version = -1; break;
                }
                break;
        }
        db.Close();
    
        return version;
    }
    

    【讨论】:

    • 几乎 - 但不完全。 +1 差点错过。两个问题:(a) 不能假设用户安装了 Access,只有 JET,以及 (b) 上述解决方案打开 Access UI 并提示用户是否打开“不安全”的文件数据库可能包含宏。由于用户甚至不知道正在使用 JET(并且 Access 不在系统要求列表中),因此我不能这样做。 (我尝试告诉 Access 它是不可见的,但如果它想提示用户,大概会解除隐形斗篷......)
    • 查看此链接以避免弹出框:support.microsoft.com/kb/317114(但这对您没有帮助,因为您不能假设用户已安装 Access - 您应该更新您的问题以注意这一点) .
    • 感谢您的帮助 - 第二个解决方案看起来很接近,但无论数据库格式如何,似乎总是返回“35”。 (我试图再给你一个 +1,但系统降低了分数而不是增加了它!)
    • 虽然不是您寻求的答案,但另一种解决方案是将属性添加到您的应用程序打开的任何数据库中,并检查您的自定义“HasBeenUpgraded”属性,如果应用程序没有找到它,只需升级它,然后将属性添加到它。
    • Microsoft.Office.Interop.Access.Application 需要安装 Access。
    【解决方案4】:

    您必须设置对 ADO 的引用,然后才能获取该属性。

    从 Access 内部

    Dim cnn As ADODB.Connection
    Set cnn = CurrentProject.Connection
    

    从 Access 外部

    Dim cnn As New ADODB.Connection
    cnn.Open Provider=Microsoft.Jet.OLEDB.4.0;Data Source=Contact.mdb
    

    最后

    Debug.Print cnn.Properties("Jet OLEDB:Engine Type").Value
    

    这个.Value会返回1到5。如果是5,说明已经在Jet4x中,否则是较早的版本。

    这是您正在研究的另一个升级技术示例:Convert MDB database to another format (JET, access version)

    【讨论】:

    • 为什么有人会在 Access 中使用 ADO?到目前为止,DAO 是 Access 本身中 Jet 数据的首选数据访问接口。
    • 有没有办法从 OLEDBConnection 获取信息?
    • 由于某种原因,ADO 似乎期待一个工作组文件,并且在打开连接时会出现 barfs “工作组信息文件丢失,仅由另一个用户打开” - 这是在我打开与 OLEDB 的连接之前。
    • OLEDBConnection 是通用连接,并非特定于 Jet,因此它没有 Jet 的连接属性。在工作组文件上 - 是否设置为工作组文件?如果是这样,您需要在连接字符串中添加类似 "Jet OLEDB:System Database=MySystem.mdw" 的内容,其中 MySystem 等于您的 DSN。使用Console.WriteLine(cnn.Properties("Jet OLEDB:Engine Type").Value) 在.NET 中我的工作进展顺利。您是否在 .NET 组件中设置了对“adodb”的引用,而不是 COM 中的“ActiveX 数据对象”?哦,还有,Access MBD完全关闭了吗?
    • @Otaku - 没有 .mdw 文件,而且从来没有。在这个问题结束之前,我可能没有机会检查其他人。谢谢你的帮助。正在使用 .NET ADODB。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多