Click here to Skip to main content
16,014,952 members
Articles / Programming Languages / Visual Basic

Problem with GO statements in SQL scripts

Rate me:
Please Sign up or sign in to vote.
1.00/5 (2 votes)
13 Apr 2011CPOL 15.8K   4   5
How to workaround the problem with GO statements in SQL scripts.

Recently, I was working on an installer application which, as part of its job, would update the database based on a SQL script. When running such scripts from the .NET environment, you would get a SqlException as it does not like the GO statements within your script. The way around that is to split your script into pieces separated by GO and run each piece separately.

You also want to make sure that either all the pieces run successfully or none is run; otherwise, it would be hard to know how far the update has gone. Using a SqlTransaction ensures that if any problem happens, the transaction is rolled back and it only gets committed if there was no problem.

The code that I ended up using is shown below. It first does the segmentation of the original script using RegEx (defined in System.Text.RegularExpressions) and then defines a SqlTransaction for the whole update:

VB
Private Sub ExecuteSqlQuery()

    Dim i As Integer

    ' Read the sql file 
    Directory.SetCurrentDirectory(txtDownLoadLocation.Text)

    Dim fileStream As New FileStream(SqlFileName, FileMode.Open, FileAccess.Read)
    Dim streamReader As New StreamReader(fileStream)

    streamReader.BaseStream.Seek(0, SeekOrigin.Begin)

    Dim allSqlString As String = streamReader.ReadToEnd()

    streamReader.Close()
    fileStream.Close()

    ' Create segments of the string called "lines" each separated by "GO" 
    Dim regex As Regex = New Regex("^GO", RegexOptions.IgnoreCase)
    Dim lines As String() = Regex.Split(allSqlString)

    Dim connectionString As String = "Data Source=" & _
        txtDatabaseServer.Text & ";Integrated Security=SSPI;"
    Dim connection As SqlConnection = New SqlConnection(connectionString)
    Dim cmd As SqlCommand = New SqlCommand()
    cmd.Connection = connection

    connection.Open()

    ' Execute as a transaction, roll back if it fails
    Dim transaction As SqlTransaction = connection.BeginTransaction()
    cmd.Transaction = transaction

    For i = 0 To lines.Length - 1
        If lines(i).Length > 0 Then
            Try
                cmd.CommandText = lines(i)
                cmd.ExecuteNonQuery()
            Catch ex As Exception
                transaction.Rollback()
                connection.Close()
                Exit Sub
            End Try
        End If
    Next

    transaction.Commit()
    connection.Close()
End Sub
This article was originally posted at http://morrisbahrami.blogspot.com/feeds/posts/default

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Architect
Australia Australia
I have over 17 years of experience in software development in a variety of fields. For last 7 years the emphasis has been mostly on .NET technology (C# and VB.NET) which includes WPF, WCF and ASP.NET AJAX. Also have SQL Server experience including SSIS and SSRS. My blog (http://morrisbahrami.blogspot.com) has a collection of tips and general info for Microsoft Developers.

Comments and Discussions

 
QuestionAdd RegexOptions.Multiline Pin
MurryGammash25-Dec-11 9:48
MurryGammash25-Dec-11 9:48 
GeneralMy observations Pin
Philippe Mori16-Apr-11 7:38
Philippe Mori16-Apr-11 7:38 
Well, I have also have the need to update a database...

However, in my case, I was not doing the whole upgrade in a single step. In my case, I have made a few "small" upgrade over the years. Often instead of using a script directly, I would have uses some functions to check if a column do exists, add a column and other changes I need to do.

Also, although the script generally works, it might not always be optimal as it would often recreate tables even though it is not strictly necessary.

I generally uses transaction but only for one step. Thus if something goes wrong during the update, only that step would be rolled back. This often works well as update are always done in same order. Thus if the database is a few version old, there will be a few updates. Also, I generally prefer to update the database one step at a time.

Talking about parsing SQL script, I do it a lot since we started with SQL Express but then later we add support for SQL Compact Edition. I parse the script to remove part that are not supported by the later database.

At first, I was using a file as the model (I uses SQL Express user instances) that I copied from a read-only empty database that I included in the setup. But when I have added support for other databases, I switch to script for generating the database. The main reason was that I do not want to create a model file for each format that I want to support. When parsing the script (to create a new database from code), I split it as required and also do appropriate changes to the script for format other that SQL Express. As I only parse file I have generated (from a ressource), the Regex code is done in a way to handle what I need. This also reduce setup size.

All my dataset where created for SQL Express. Thus also any command where create for that database. I have made my own adapter based on generated code and modify the code to adjust queries for other database. Also, stored procedure are skipped (I have alternate code) when not supported by the database.

If I would start a new project, I would probably check what alternative are availables. My solution is somewhat hard to maintain when changes are made. But SQL Compact Edition support was added after most update to the database model and by now, the model is relatively stable so it was seldom a problem.

Maybe, I would look at EF, Linq to SQL or some other newer technologies if I would start now.

Supporting SQL Compact Edition was somehow hard and I might still have some problem in the application in some area that are less used. For example, identity does not works automatically as it was the case in SQL Express so many update queries were initially failing. I have added some code to handle that. At the same time, I added SQL Compact Edition, I tryied to add SQLite also... but it was not completed as I need only one alternative and it was somehow harder to convert script from SQL Express to SQLite in some area.
Philippe Mori

GeneralMy vote of 1 Pin
Ravi Sant14-Apr-11 0:53
Ravi Sant14-Apr-11 0:53 
General[My vote of 1] Good luck with that... Pin
Irasimus13-Apr-11 9:59
Irasimus13-Apr-11 9:59 
GeneralRe: [My vote of 1] Good luck with that... Pin
Morris Bahrami14-Apr-11 14:40
Morris Bahrami14-Apr-11 14:40 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.