【问题标题】:Check sql script valid检查 sql 脚本是否有效
【发布时间】:2009-12-07 15:43:45
【问题描述】:

作为发布的一部分,我们针对数据库运行大量 PL/SQL 脚本。最近有人将; 留在了一个脚本的行尾,该脚本被称为另一个脚本,因此这意味着该脚本没有运行。因为这并没有导致错误,只是没有运行,所以花了相当长的时间来追踪发生了什么。

我想在运行脚本之前检查脚本中是否缺少末尾的 ; 或后面的行中的 /。这变得更加复杂,因为脚本中的“行”实际上可能跨越多行,如果它是语句或代码块。

对我来说,这似乎是这样做的,我将不得不解析脚本,然后检查它们是否符合上述要求。

我找到了 ANTLR 并想知道这是否是一种方法,因为似乎有 existing PL/SQL grammars 但看起来这将是一个简单的检查的逐步学习曲线。

有没有人知道一种简单的方法或任何其他工具、eclipse 插件等,我可以使用它们来检查脚本中缺少最后一行 ; 或后面一行 / 的行?

更新 我们已经完成了大部分工作Tom H suggested。脚本在我们的测试服务器中运行,我们有一个在最后更新的版本表。问题是容器脚本中缺少分号意味着一个脚本没有运行,但其余的包括更新版本号的脚本运行时没有错误。因此,这个问题只是在测试中得到了很大的帮助。这需要在运行添加了缺少的分号的脚本之前恢复数据库,因此基本上导致半天的测试时间丢失。如果有一种简单的方法可以在将脚本运行到测试服务器之前检查这一点,它可以节省相当多的时间。

【问题讨论】:

  • 在我使用的数据库版本控制系统中,在更新脚本开始时,我设置版本号并为其分配“运行”标志,然后在 脚本结束

标签: sql parsing plsql antlr


【解决方案1】:

我同意 MattH 的观点,您可能会以错误的方式处理此问题。我只需在所有脚本的末尾添加一个插入语句,将“版本”行插入数据库中的表中。在部署脚本结束时,检查版本表中是否包含所有正确的行是一项简单的任务。

此外,您应该让所有发布脚本完全按照它们在生产环境中的方式运行,以针对您的 QA 服务器。这就是所有测试发生的地方。除了发布步骤中的内容之外,您永远不会对服务器执行任何操作 - 您只运行发布脚本,如果这些发布脚本发生更改,那么您使用它们刷新 QA 服务器并重做测试。

当您投入生产时,您的发布过程已经过全面测试。作为故障安全措施,您还可以使用 Red Gate 的 SQL 比较和 SQL 数据比较等工具来检查生产是否与 QA 服务器匹配。数据比较将仅针对某些表(查找表等)。如果您对主要表(1M 行等)进行了数据更改,那么您可以修改自定义脚本以检查它们是否正确。

【讨论】:

  • 我们已经完成了大部分工作,问题是它只是通过测试才发现的。如果有一种方法可以在脚本运行到测试服务器之前快速检查此类脚本,则可以节省大量时间。
  • 正如我当时所说,跟踪已成功针对数据库运行的所有脚本的日志表或版本表可能是您最安全的选择。
【解决方案2】:

即使每个版本的脚本都不同(而不是创建或替换数据库对象的已定义源代码控制结构的一部分),我也会采用将脚本分解为每个文件的最基本工作单元并部署的做法他们通过 Ant 使用标准的 sql 任务。你可能有这些类型的脚本:

  • 创建或替换 dbobject...
  • SQL DML 脚本
  • 匿名 PL/SQL 块

如果您对一致的语句分隔符进行标准化(我建议使用“/”,因为它适用于上述所有情况)并将部署设置为因错误而失败,那么 Ant 将部署所有文件或说明原因不能。

我认为,如果没有关于分隔符选择或每个文件语句的标准,那么解析一个或多个 SQL 和/或 PLSQL 语句的文件并找到丢失的分隔符将非常困难。

【讨论】:

    【解决方案3】:

    只是一个想法,但你是不是走错路了?

    我假设,在文件级别,文件中缺少分号不是问题吗?但是只有在通过批处理运行时才成为问题?如果是这种情况,也许您可​​以更改批处理以应对这种情况。

    如果它是文件,那么测试应该已经把它捡起来了。您不想解析输入文件以确保它们能够编译等。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-01-09
      • 1970-01-01
      • 2011-04-29
      • 1970-01-01
      • 2013-06-24
      • 2015-04-11
      • 1970-01-01
      相关资源
      最近更新 更多