I have a very simple C# command shell app that executes a sql script generated by SQL Server for scripting schema and data. It\'s blowing up on the \"GO\" statements. Error
As others mentioned, split your string by GO
statements. But be careful, you may have the text "GO"
in other parts of your script. You might also have whitespace before or after the GO statement, and you might have comments on the line after the GO statement also. Any of that would be valid in SSMS, so you may want to test for it.
Here is the method I use:
private static IEnumerable<string> SplitSqlStatements(string sqlScript)
{
// Split by "GO" statements
var statements = Regex.Split(
sqlScript,
@"^[\t ]*GO[\t ]*\d*[\t ]*(?:--.*)?$",
RegexOptions.Multiline |
RegexOptions.IgnorePatternWhitespace |
RegexOptions.IgnoreCase);
// Remove empties, trim, and return
return statements
.Where(x => !string.IsNullOrWhiteSpace(x))
.Select(x => x.Trim(' ', '\r', '\n'));
}
GO is not a valid QA command, it is a batch separator... It is processed by Enterprise Manager to separate SQL scripts. As such, it will work in Enterprise Manager, but not in database calls from C# or other external programs....
1 additional point to "iamkrillin"'s answer, for using the old DLLs to make it work.
after adding the references to these DLLs
Microsoft.SqlServer.ConnectionInfo.dll , Microsoft.SqlServer.Management.Sdk.Sfc.dll Microsoft.SqlServer.Smo.dll , Microsoft.SqlServer.SqlEnum.dll
from a place like this: "C:\Program Files (x86)\Microsoft SQL Server\130\SDK\Assemblies\Microsoft.SqlServer.ConnectionInfo.dll" to the project, I needed to add the following "using" directives to the top of my code file:
using Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlServer.Management.Common;
....
string query = @" //sql multi-command text here"
using (SqlConnection thisconn = new SqlConnection(connectionString)) {
Server db = new Server(new ServerConnection(thisconn));
db.ConnectionContext.ExecuteNonQuery(query);
}
As an alternative to massaging the scripts to make them runnable through C#, you could just run them as-is by using the sqlcmd
utility. Lot of details at:
http://technet.microsoft.com/en-us/library/ms180944.aspx
By using sqlcmd, you can script out the execution of any number of your SQL Server generated scripts, without stripping out the Go
statements.
Just replace "GO" with "" and it works.
SqlCommand command = new SqlCommand(script.Replace("GO", ""), connection);
command.CommandType = CommandType.Text;
command.ExecuteNonQuery();
The top answer has a mistake. I just tested a working solution: You should allow space,';' or new line before GO
var scripts = Regex.Split(statementText, @"(\s+|;|\n|\r)GO", RegexOptions.Multiline);
foreach(var splitScript in scripts.Where(splitScript => !splitScript.IsNullOrWhiteSpace())) {
cmd.CommandText = splitScript;
cmd.ExecuteNonQuery();
}