1

I am using Regex.Split to split a SQL script on the keyword "GO". My problem here is that I cannot seem to get my head around how to get the Regex to do the split. My regex expression also splits on "GO" even if it's in a SQL statement like:

Insert into  x(a,b) values(‘please go get some text’,’abc’)

But I only want it to split on the keyword "GO". Any suggestions?

EDIT: I am using c#. at the moment my regex is simply:

  foreach (string batch in Regex.Split(script, "\\bGO\\b", RegexOptions.IgnoreCase))
  {
    yield return batch;
  }
Chad Birch
  • 73,098
  • 23
  • 151
  • 149
Draco
  • 16,156
  • 23
  • 77
  • 92

5 Answers5

4

This is pretty much impossible without implementing a complete SQL parser (which you probably do not want to do), in the really correct way.

An alternative would be to resort to some hacks (i.e. ignore sections of the text that are within quotes), but this will still not work if your SQL contains the text 'GO' at some other place, e.g. 'SELECT * FROM GO'.

Martin Probst
  • 9,497
  • 6
  • 31
  • 33
  • +1, regex does not have the power to parse SQL, period. You may need to rethink your requirements. Writing a full SQL parser is hugely non-trivial. – bobince Mar 11 '09 at 15:23
  • @bobince: "hugely non-trivial"... oxymoron ? ;-) – Cerebrus Mar 13 '09 at 05:36
  • Err... how would that be an oxymoron? trivial would be small, non-trivial is therefore large... if anything it's redundant. – CodeRedick Mar 13 '09 at 05:44
4

Split on GOs on a line by themselves, like:

foreach (string batch in Regex.Split(script, "^GO$\\n", RegexOptions.IgnoreCase | RegexOptions.Multiline))
{
    yield return batch;
}

Depending on where your script is coming from you may need to change that to "^GO$\\r\\n"

Gordon Bell
  • 13,337
  • 3
  • 45
  • 64
3

You could search for "go" on a line by itself. Not guaranteed to always work, but more likely to work.

Joel
  • 19,175
  • 2
  • 63
  • 83
2

You could try something like

/;\sGO\s;/i

With that you'll be covering every GO sentence, independently if they are in just one line or not (i.e. semi-colons in other lines).

If you're using queries for further execution, the you might want to add the semi-colon back to each query.

Be warned that if an occurrence of "; GO;" happens inside an insert string, then there's no way to achieve your goal without a proper SQL parser.

Seb
  • 24,920
  • 5
  • 67
  • 85
0

Here's how I solved this with a regex.

var statements = Regex.Split(sql, @"^\s*GO\s*$", 
    RegexOptions.IgnoreCase | RegexOptions.Multiline);            

This splits on "GO" when it is on its own line, and optionally surrounded by whitespace. Those appear to be the rules enforced by SSMS - putting GO on a line with any other statement causes an error (semi-colons or no).

Note that it will still break if your script has GO statements on their own line inside block comments. That's the only fault I can think of with it.

The bullet-proof solution would be to use SMO, as detailed in this answer.

Community
  • 1
  • 1
Blorgbeard
  • 101,031
  • 48
  • 228
  • 272