4

I and trying to create a method to run a .sql file on an SQL Server database.

The code i have is:

SqlConnection dbCon = new SqlConnection(connstr);
FileInfo file = new FileInfo(Server.MapPath("~/Installer/JobTraksDB.sql"));
StreamReader fileRead = file.OpenText();
string script = fileRead.ReadToEnd();
fileRead.Close();

SqlCommand command = new SqlCommand(script, dbCon);
try
{
    dbCon.Open();
    command.ExecuteNonQuery();
    dbCon.Close();
}
catch (Exception ex)
{
    throw new Exception("Failed to Update the Database, check your Permissions.");
}

But i keep getting errors about "incorrect syntax near keyword 'GO'" My SQL File starts like this: (Generated from SQL Management Studio)

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[Job_Types](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [Name] [varchar](50) NOT NULL,
 CONSTRAINT [PK_JobTypes] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO

How should i be executing this script?

3 Answers 3

5

This is how we do it:

    protected virtual void ExecuteScript(SqlConnection connection, string script)
    {
        string[] commandTextArray = System.Text.RegularExpressions.Regex.Split(script, "\r\n[\t ]*GO");

        SqlCommand _cmd = new SqlCommand(String.Empty, connection);

        foreach (string commandText in commandTextArray)
        {
            if (commandText.Trim() == string.Empty) continue;
            if ((commandText.Length >= 3) && (commandText.Substring(0, 3).ToUpper() == "USE"))
            {
                throw new Exception("Create-script contains USE-statement. Please provide non-database specific create-scripts!");
            }

            _cmd.CommandText = commandText;
            _cmd.ExecuteNonQuery();
        }

    }

Load the contents of your script using some file-reading function.

Sign up to request clarification or add additional context in comments.

2 Comments

I can see a bug: Assume I have a procedure named sp and the script is "sp". commandText.Substring(0, 3) will throw an IndexOutOfRangeException.
@Mehrdad: Yes, common mistake, assuming that String.Substring(0, xxx) works exactly like the VB function Left(xxx). :-)
5

GO is not a T-SQL statement. It's a hint for client tools such as sqlcmd or Management Studio to split up statements and send them as individual batches. They use a GO command on its own line as a marker to indicate the end of a batch. You shouldn't send the file as a whole to SQL Server.

Side note: There's a File.ReadAllText method that you can use instead of those three lines.

4 Comments

ok, then whats the best way to perform a batch create table function? (this is for a web installer)
The naive way is to split the file by lines containing the GO command and send each part to SQL Server in a loop. However, I think you are reinventing the wheel as some open source projects (e.g. DotNetNuke) use a similar technique for their installation. You can check their source out.
check my answer. Code sample does the job perfectly.
I know there are a few open source web installers out there but this is pretty much all i need it to do... thanks for your answers guys!
1

If you are willing to include a couple of the SMO dlls, you can execute a script with a few lines of code:

using Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlServer.Management.Common;

    public void Exec(string script)
    {
        using (var conn = new SqlConnection(ConnString))
        {
            var server =  new Server(new ServerConnection(conn));
            server.ConnectionContext.ExecuteNonQuery(script, ExecutionTypes.ContinueOnError);
        }
    }

The SMO library handles the GO issue so you don't have to. You will need to reference the following assemblies:

Microsoft.SqlServer.ConnectionInfo.dll

Microsoft.SqlServer.Management.Sdk.Sfc.dll

Microsoft.SqlServer.Smo.dll

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.