【问题标题】:Validate Microsoft Access SQL验证 Microsoft Access SQL
【发布时间】:2017-11-09 09:46:42
【问题描述】:

我有一长串 SQL 脚本。它们都是更新语句。它用于访问数据库。我想在运行之前验证脚本。首先,我想确保可以解析查询。 IE。 SQL 至少在语法上是正确的。其次,我想确保查询在数据库结构方面是有效的——即没有丢失的列或列的类型错误等。但是,我不希望查询被实际执行。这样做的目的是在流程开始之前进行快速验证,因为该流程需要几个小时,一个语法错误可能会浪费某人一天的时间。

我可能会用 .net 用 C# 编写该工具,但如果有一个预构建的工具会更好。我可能会使用 Access API。在 SQL Server 中,这是非常直接的。您可以在运行之前在 SQL Server 管理工作室中验证查询。它可以很好地指示 SQL 是否会完成。

我该怎么做呢?

编辑:下面的答案解决了检查语法的问题。但是,我仍然希望能够验证查询的语义内容是否正常。但是,我认为如果不实际运行查询,这在 Access 中可能是不可能的。请告诉我我错了。

【问题讨论】:

    标签: c# sql validation ms-access


    【解决方案1】:

    我不能 100% 确定 Access 的工作方式是否与传统数据库相同,但对于主流 RDMBS,运行查询时实际上会发生三个不同的步骤:

    • 准备
    • 执行
    • 获取

    大多数人没有注意到这种区别,因为他们只是点击“运行”并看到结果回来。

    在启动和拉取数据之前,实际上是编译语句的“执行”。

    当您使用 ADO 时,您实际上可以将这三个事件视为对数据库的三个单独调用。这意味着您可以捕获执行步骤以查看它是否失败,如果成功,则无需您实际获取结果。

    OleDbConnection conn = new OleDbConnection();
    conn.ConnectionString = String.Format("{0}{1}",
        @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=", @"c:\Access\MyDb.accdb");
    conn.Open();
    
    bool valid;
    using (OleDbCommand cmd = new OleDbCommand("select [Bad Field] from [Table]", conn))
    {
        try
        {
            OleDbDataReader reader = cmd.ExecuteReader();
            valid = true;
            reader.Close();   // Did not ever call reader.Read()
        }
        catch (Exception ex)
        {
            valid = false;
        }
    }
    

    现在valid 表示语句是否编译。

    如果你想真正花哨,你可以解析异常结果来找出命令失败的原因。

    【讨论】:

    • 非常好。是的。我不确定 access 是否支持这一点,但它看起来绝对是最好的选择。
    • 我试过这个。有用!这是验证语法的好方法,因为驱动程序为语法错误提供了不同的异常。这意味着我可以在空白数据库上测试更新语句,而忽略丢失表等异常的事实。
    • 唯一的问题是我无法检查语义错误,例如缺少表或不正确的数据类型等。不过,这是一个很好的开始。
    • 这会非常棘手并且涉及大量解析,但您可以在 Access 中查看MSysObjects,其中包含所有表。也就是说,您必须处理它可能发生在“from”或“join”(可能是其他构造)之后,处理空格,处理可选括号......听起来很痛苦,即使使用正则表达式(尽管它们会帮助很多)。很高兴这对您有所帮助 - 感谢您的反馈。
    • 不一定。有语言解析器可以将 SQL 转换为对象模型。例如,Actipro 有一个语法高亮 UI 组件,它利用具有可定义语言的解析器。我们使用语法高亮来处理 SQL。这是一个很好的工具。唯一的问题是 Access SQL 是非标准的,因此不太符合要求。我必须自定义语言。而且,即便如此,在解析查询后重新创建 Access 所做的工作也将是一项艰巨的工作。只是想知道是否还有其他想法......
    【解决方案2】:

    Access 支持其 Connection 对象上的事务。尝试在事务中执行 SQL 语句并始终调用 Rollback。将整个尝试包装在 Try/Catch 块中,以评估语句是否成功执行。

    【讨论】:

    • 我想到了这个。这是一个不错的想法,但违背了目的。问题是这个过程需要几个小时才能运行。因此,如果一切正常,验证 SQL 仍然需要很长时间。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-06-19
    • 1970-01-01
    • 1970-01-01
    • 2011-01-14
    • 1970-01-01
    • 2017-09-02
    • 2010-09-14
    相关资源
    最近更新 更多