I was trying to have some C# code execute a database script to set up an MS SQL database, but the script was failing. Google helped me out (a bit lazy this sunday evening) by providing this blog post: How to run a SQL database installer from your .net application, by David Szabo. However, the script still failed me (much later in the script, but still). This time it was more obvious. David's solution to the problem was simply to split the string containing the script on the word "GO". In my case though, the script included the creation of a stored procedure containing a GOTO statement. Since I was splitting the string on the characters "GO", GOTO lost its verb, and the remaining part got to start a new element in my string array of commands to execute. So, I altered the solution slightly to include the carriage-return and line feed characters before and after the GO statement in the script:

// Runs the given database script on the given connection. The script
// is divided into commands by splitting the incoming script string
// on the "GO" word, including the surrounding carriage-return and
// newline characters, in order to avoid splitting on other occurrances
// of the characters "GO"
private static void RunScript(SqlConnection connection, string script)
{
    Regex regex = new Regex(@"\r{0,1}\nGO\r{0,1}\n");
    string[] commands = regex.Split(script);

    for (int i = 0; i < commands.Length; i++)
    {
        if (commands[i] != string.Empty)
        {
            using(SqlCommand command = new SqlCommand(commands[i], connection))
            {
                command.ExecuteNonQuery();
                command.Dispose();
            }
        }
    }
}

Of course you might want to extend the code with exception handling to your liking.

UPDATED 27 February 2009: I altered the code above to use Regex for splitting the string, since I came across some SQL script files in which the line breaks consisted only of '\n', lacking the preceding '\r'. TheRegex takes care of this by making the '\r' character optional, but keeping the '\n' mandatory. Don't forget to addusing System.Text.RegularExpressions to your code file to get this to work.

Bookmark and Share

Comments

October 29. 2008 11:53

Marc Rousssel

And what if we would like to return a DataTable out of it.  A DataSet because de script returns a DataTable

Marc Rousssel

October 31. 2008 16:43

fredrik

Marc, in that case that I was working with I had a large SQL script setting up a database schema, so it consisted of a large number of individual SQL statements, none of which returned any data that I was interested in (this is why I split the string on "GO"). If you have an SQL statement and want to fill a DataTable with the result, I would do something along these lines:

SqlConnection conn = new SqlConnection(@"[your connection string here]");
SqlCommand cmd = new SqlCommand(@"[your sql statement here]", conn);
cmd.CommandType = CommandType.Text;
SqlDataAdapter sda = new SqlDataAdapter(cmd);
DataTable dt = new DataTable();
sda.Fill(dt);


Now the DataTable (dt) contains the result of the SQL statement. Note that you do not need to explicitly open the connection to the database; this is automatically taken care of in the call to the Fill method of the SqlDataAdapter. However, if you do open the connection object before calling the Fill method, the connection object will remain open after the call, and you will need to close it.

fredrik

May 28. 2009 19:26

Ben Pearce

Take a look at this SO answer:
stackoverflow.com/.../40830#40830

It shows how to execute the script without removing the GO statements. I have tested this and it works.

Ben Pearce

May 28. 2009 19:51

fredrik

Thanks for that link Ben, looks worth checking out.

fredrik

Add comment


(Will show your Gravatar icon)

  Country flag

biuquote
  • Comment
  • Preview
Loading