简体   繁体   English

检查sql脚本是否有效

[英]Check sql script valid

As part of a release we run a load of PL/SQL scripts against a database. 作为发布的一部分,我们针对数据库运行大量PL / SQL脚本。 Recently someone left the ; 最近有人离开了; off the end of a line in one script that was called another script so this meant that script did not get run. 在一个被称为另一个脚本的脚本中的一行结束,这意味着脚本没有运行。 Because this did not cause an error, it just didn't get run, it took quite a while to track down what had happened. 因为这不会导致错误,它只是没有运行,需要花费很长时间来追踪发生的事情。

I want to check the scripts before they are run for lines in them that are missing either a ; 我想检查脚本,然后再运行它们中缺少a的行; at the end or a / on the line after. 在结束时或在/之后。 This is made more complicated as 'lines' in the script could actually span more than one line if it is statement or block of code. 这变得更加复杂,因为如果它是语句或代码块,脚本中的“行”实际上可能跨越多行。

To me this seems like to do this I'm going to have to parse the scripts then check they meet the above. 对我来说这似乎是这样做我将不得不解析脚本,然后检查他们是否满足上述要求。

I've found ANTLR and wonder if this might be a way to do it since there seem to be existing PL/SQL grammars but looks like that's going to be a step learning curve for what's just a simple check. 我找到了ANTLR,并想知道这是否可能是一种方法,因为似乎有现有的PL / SQL语法,但看起来这只是一个简单检查的步骤学习曲线。

Does anyone know an easy way or any other tools, eclipse plugins etc that I can use to check for lines in the scripts that are missing either a ; 有没有人知道一个简单的方法或任何其他工具,eclipse插件等,我可以用来检查缺少任何一个脚本中的行; at the end or a / on the line after? 在最后还是/在线之后?

Update We already do most of the stuff Tom H suggested . 更新我们已经完成了Tom H建议的大部分内容。 The scripts are run into our test server and we have a version table that gets updated at the end. 脚本运行到我们的测试服务器中,我们有一个版本表,最后会更新。 The problem was that the missing semi-colon in the container script meant one script did not get run but the rest including the one to update the version number ran without errors. 问题是容器脚本中缺少的分号意味着一个脚本没有运行但其余的包括更新版本号的脚本运行没有错误。 Therefore the problem only got picked up quite a way into testing. 因此,这个问题只能在测试中得到很好的应用。 This needed the database restored before running the scripts with the missing semi-colon added so basically resulted in half a day of testing time being lost. 这需要在运行脚本之前恢复数据库,并添加缺少的分号,因此基本上导致半天的测试时间丢失。 If there was a simple way to check this before running the scripts into the test server it could save quite a bit of time. 如果将脚本运行到测试服务器之前有一种简单的方法来检查它,它可以节省相当多的时间。

I agree with MattH that you may be going about this the wrong way. 我同意MattH你可能会以错误的方式解决这个问题。 I would just add an insert statement to the end of all of your scripts which insert a "version" row into a table in the database. 我只是在所有脚本的末尾添加一个insert语句,它将“version”行插入数据库的表中。 At the end of your deployment scripts it's then an easy task to check that the version table has all of the correct rows in it. 在部署脚本结束时,检查版本表中是否包含所有正确的行是一项简单的任务。

Also, you should have all of your release scripts being run exactly as they will be in production against your QA server. 此外,您应该让所有发布脚本的运行方式与针对QA服务器的生产完全相同 That's where all of the testing takes place. 这就是所有测试的地方。 You never do anything to the server besides what is in your release steps - you only run the release scripts and if those release scripts are ever changed then you refresh the QA server with them and redo testing. 除了发布步骤之外,您永远不会对服务器执行任何操作 - 您只运行发行脚本,如果这些发行脚本曾经更改过,那么您可以使用它们刷新QA服务器并重做测试。

When you go to production your release process has then been fully tested. 当您开始生产时,您的发布过程已经过全面测试。 As a fail safe measure you can also use tools like Red Gate's SQL Compare and SQL Data Compare to check that production matches the QA server. 作为故障安全措施,您还可以使用Red Gate的SQL Compare和SQL Data Compare等工具来检查生产是否与QA服务器匹配。 The data compare would only be against certain tables (look-up tables, etc.). 数据比较仅针对某些表(查找表等)。 If you have data changes to major tables (1M rows, etc.) then you can right a custom script to check that they are correct. 如果您对主表(1M行等)进行了数据更改,那么您可以右键自定义脚本以检查它们是否正确。

Even if the scripts are different for every release (and not part of a defined source control structure that creates or replaces database objects) I would adopt a practice of breaking the scripts down into the most fundamental units of work per file and deploying them through Ant with the standard sql task. 即使脚本对于每个版本都是不同的(并且不是创建或替换数据库对象的已定义源控件结构的一部分),我也会采用将脚本分解为每个文件的最基本工作单元并通过Ant部署它们的做法。使用标准的sql任务。 You probably have these types of scripts: 您可能有这些类型的脚本:

  • CREATE or REPLACE dbobject... 创建或替换dbobject ...
  • SQL DML scripts SQL DML脚本
  • Anonymous PL/SQL blocks 匿名PL / SQL块

If you standardize on a consistent statement delimiter (I suggest using "/" since it works with all of the cases above) and set the deployment to fail on error, then Ant will either deploy all of the files or indicate why it couldn't. 如果你在一致的语句分隔符上标准化(我建议使用“/”,因为它适用于上面的所有情况)并将部署设置为出错时失败,那么Ant将部署所有文件或指出为什么它不能。

I think it would be very difficult to otherwise parse files of one or more SQL and/or PLSQL statements and find missing delimiters if there are no standards on delimiter choice or statements per file. 我认为如果没有关于分隔符选择或每个文件的语句的标准,否则解析一个或多个SQL和/或PLSQL语句的文件并找到缺少的分隔符将是非常困难的。

Just a thought, but are you going about this the wrong way? 只是一个想法,但你是否采取了错误的方式?

I assume, at the file-level, the lack of a semi colon in the file was not a problem? 我假设,在文件级别,文件中缺少半冒号不是问题吗? but it only became a problem when run via the batch processing? 但它只是通过批处理运行时成为一个问题? If that's the case maybe you can change your batch processing to cope with this. 如果是这种情况,也许您可​​以更改批处理以应对此问题。

If it was the file, then testing should have picked it up. 如果它是文件,那么测试应该已经把它拿起来了。 You don't want to parse your input files to make sure they compile etc. 您不想解析输入文件以确保它们编译等。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM