Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I support the SQL GO statement in a Java / jtds application?

I'm working on a Java based OSS app SqlHawk which as one of its features is to run upgrade sql scripts against a server.

Microsoft have made it a convention to split a script into batches with the GO statement, which is a good idea but just asking for false matches on the string.

At the moment I have a very rudimentary:

// split where GO on its own on a line
Pattern batchSplitter = Pattern.compile("^GO", Pattern.MULTILINE);
...
String[] splitSql = batchSplitter.split(definition);
...

which kind of works but is prone to being tripped up by things like quoted GO statements or indentation issues.

I think the only way to make this truly reliable is to have an SQL parser in the app, but I have no idea how to go about this, or whether that might actually end up being less reliable (especially given this tool supports multiple DBMSs).

What ways could I solve this problem? Code examples would be very helpful to me here.

Relevant sqlHawk code on github.

Currently using jtds to execute the batches found in the scripts.

like image 988
Tim Abell Avatar asked May 24 '12 09:05

Tim Abell


People also ask

What is the GO command in SQL?

GO is not a Transact-SQL statement; it is a command recognized by the sqlcmd and osql utilities and SQL Server Management Studio Code editor. SQL Server utilities interpret GO as a signal that they should send the current batch of Transact-SQL statements to an instance of SQL Server.

What is go in SQL stored procedure?

The GO command is frequently used inside T-SQL code to use batches. It is not a T-SQL statement, but it is a command recognized by native SQL Server tools like the SSMS, the SQLCMD, and OSQL (SQLCMD is the command-line to handle SQL Server and osql is an old version of SQLCMD that may be removed someday).

What is Microsoft JDBC driver for SQL Server?

The Microsoft JDBC Driver for SQL Server is a Type 4 JDBC driver that provides database connectivity through the standard JDBC application program interfaces (APIs) available on the Java platform. The driver downloads are available to all users at no extra charge.

Where should I put sqljdbc4 jar?

You have to add sqljdbc. jar or sqljdbc4. jar to the IDE classpath.


2 Answers

GO is a client batch seperator command. You can replace it with ;. It should not be sent in your EXEC dynamic SQL.

USE master
GO --<----- client actually send the first batch to SQL and wait for a response
SELECT * from sys.databases
GO

Should be translated in

Application.Exec("USE master");
Application.Exec("SELECT * from sys.databases");

or you can write it this way:

Application.Exec("'USE master;SELECT * from sys.databases")

More about GO http://msdn.microsoft.com/en-us/library/ms188037(v=sql.90).aspx

like image 101
PollusB Avatar answered Oct 31 '22 16:10

PollusB


Ok, so this isn't going to be exactly what you want, but you might find it a start. I released SchemaEngine (which forms the core of most of my products) as open source here. In there, you will find C# code that does what you want very reliably (i.e. not tripping up with strings, comments etc etc). It also support the 'GO x' syntax to repeat a batch x times.

If you download that and have a look in /Atlantis.SchemaEngine/Helpers you'll find a class called BatchParser.cs which contains a method called ParseBatches - which does pretty much what it says on the tin.

like image 24
Matt Whitfield Avatar answered Oct 31 '22 18:10

Matt Whitfield