9

I want to run my .sql script file using my ASP.NET website through ADO.NET. How it could be it is not working?

When I try

'dbScript is a string and contains contents of the .sql file'
Dim cmd As New SqlCommand(dbScript, con)
Try
    con.Open()
    cmd.ExecuteNonQuery()
Catch ex As Exception
Finally
    con.Close()
    cmd.Dispose()
End Try

I get exceptions when GO statement executed in script. How can I fix this problem?

abatishchev
  • 98,240
  • 88
  • 296
  • 433
Muhammad Adnan
  • 1,375
  • 6
  • 19
  • 40

5 Answers5

15

See my blog post about Handling GO Separators in SQL - The Easy Way. The trick is to use SMO's ExecuteNonQuery() method. For example, here's some code that will run all scripts in a directory, regardless of GO separators:

    using System;
    using System.IO;
    using System.Data.SqlClient;
    using System.Collections.Generic;

    //Microsoft.SqlServer.Smo.dll
    using Microsoft.SqlServer.Management.Smo;
    //Microsoft.SqlServer.ConnectionInfo.dll
    using Microsoft.SqlServer.Management.Common;

    public class RunAllSqlSriptsInDirectory
    {
        public static void Main()
        {
            string scriptDirectory = "c:\\temp\\sqltest\\";
            string sqlConnectionString = "Integrated Security=SSPI;" + 
                "Persist Security Info=True;Initial Catalog=Northwind;Data Source=(local)";
            DirectoryInfo di = new DirectoryInfo(scriptDirectory);
            FileInfo[] rgFiles = di.GetFiles("*.sql");
            foreach (FileInfo fi in rgFiles)
            {
                FileInfo fileInfo = new FileInfo(fi.FullName);
                string script = fileInfo.OpenText().ReadToEnd();
                SqlConnection connection = new SqlConnection(sqlConnectionString);
                Server server = new Server(new ServerConnection(connection));
                server.ConnectionContext.ExecuteNonQuery(script);
            }
        }
    }
Jon Galloway
  • 52,327
  • 25
  • 125
  • 193
  • 5
    Note though that taking a dependency on SMO will require your application to pre-install the SMO redistributable, a minor inconvenience. But the real deal-killer is that SMO is version specific and will flat out refuse to connect to higher versions of SQL: an application developed using the SMO from SQL 2k5 will not connect to a SQL Server 2k8, requiring the developer to release a new version of its app that uses SMO 2k8. – Remus Rusanu Jul 27 '09 at 23:08
  • Remus, good points. These aren't as big of a deal when you're running scripts on your own website Muhammad is asking. – Jon Galloway Jul 28 '09 at 00:01
  • Thanks for your help. hope to find generic and platform independent solution soon. if you do pls share here. thanks again – Muhammad Adnan Jul 28 '09 at 15:10
  • 1
    You should wrap the SqlConnection declaration in a in using() – Keltex Nov 21 '09 at 16:13
  • I have found that using this technique causes some unmanaged code inside the SMO library to load. If you are using .Net 4.0 you'll run into this: "Mixed mode assembly is built against version 'v2.0.50727' of the runtime and cannot be loaded in the 4.0 runtime without additional configuration information." See: http://stackoverflow.com/questions/1604663/what-does-uselegacyv2runtimeactivationpolicy-do-in-the-net-4-config – William Leader Apr 09 '13 at 16:23
7

GO is not a Transact-SQL statement, is a tools batch delimiter. The server rightfully complain of a syntax error when GO is encountered in a batch. You need to split the file into batches and then execute individual batches. Use a regular expression that splits the file inot batches and recognizes GO case insensitive on a single line.

Remus Rusanu
  • 288,378
  • 40
  • 442
  • 569
3

There is one minor problem with using splitting method to execute batches. The problem is comments. Say you have no power over the content of the files. You just need to execute it. GO within a multi-line comment will be the problem in every solution example here that is splitting the sql code using "GO" as the separator. Example:

[some sql code]
GO

/* start of commented out sql code ***********
[some sql code]
GO
end of commented out sql code ****************/

[some sql code]
GO

This will require some more complicated parsing than just a split. This won't work anymore:

Regex regex = new Regex("^GO", RegexOptions.IgnoreCase | RegexOptions.Multiline);
string[] lines = regex.Split(sql);

This code also ignores that spaces may lead the GO.

Prasad Jadhav
  • 5,090
  • 16
  • 62
  • 80
Eugene
  • 31
  • 1
2

It's because GO isn't actually a native TSQL statement, it's used in Management Studio/Enterprise Manager to divide the script into batches.

You either need to:
1) split it into multiple individual scripts on each GO statement
2) use the Server class within SQL Management Objects, as exampled here

AdaTheDev
  • 142,592
  • 28
  • 206
  • 200
0

You would have to do two pass parsing. First time pass is to remove all the comments and build a new string. The second pass is to use the REGEX split based on the GO keyword.