Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8447725
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 10, 20262026-06-10T10:15:07+00:00 2026-06-10T10:15:07+00:00

I came across this tutorial to understand how to execute SQL scripts with GO

  • 0

I came across this tutorial to understand how to execute SQL scripts with GO statements.
Now I want to know what can I get the output of the messages TAB.

With several GO statements, the output would be like this:
1 rows affected
912 rows affected
…

But server.ConnectionContext.ExecuteNonQuery() can return only an int, while I need all the text. In case there is some error in some part of query, it should put that also in the output.
Any help would be appreciated.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-10T10:15:08+00:00Added an answer on June 10, 2026 at 10:15 am

    The easiest thing is possibly to just print the number you get back for ExecuteNonQuery:

    int rowsAffected = server.ConnectionContext.ExecuteNonQuery(/* ... */);
    if (rowsAffected != -1)
    {
         Console.WriteLine("{0} rows affected.", rowsAffected);
    }
    

    This should work, but will not honor the SET NOCOUNT setting of the current session/scope.

    Otherwise you would do it like you would do with “plain” ADO.NET. Don’t use the ServerConnection.ExecuteNonQuery() method, but create an SqlCommand object by accessing the underlying SqlConnection object. On that subscribe to the StatementCompleted event.

    using (SqlCommand command = server.ConnectionContext.SqlConnectionObject.CreateCommand())
    {
        // Set other properties for "command", like StatementText, etc.
    
        command.StatementCompleted += (s, e) => {
             Console.WriteLine("{0} row(s) affected.", e.RecordCount);
        };
    
        command.ExecuteNonQuery();
    }
    

    Using StatementCompleted (instead, say, manually printing the value that ExecuteNonQuery() returned) has the benefit that it works exactly like SSMS or SQLCMD.EXE would:

    • For commands that do not have a ROWCOUNT it will not be called at all (e.g. GO, USE).
    • If SET NOCOUNT ON was set, it will not be called at all.
    • If SET NOCOUNT OFF was set, it will be called for every statement inside a batch.

    (Sidebar: it looks like StatementCompleted is exactly what the TDS protocol talks about when DONE_IN_PROC event is mentioned; see Remarks of the SET NOCOUNT command on MSDN.)

    Personally, I have used this approach with success in my own “clone” of SQLCMD.EXE.

    UPDATE: It should be noted, that this approach (of course) requires you to manually split the input script/statements at the GO separator, because you’re back to using SqlCommand.Execute*() which cannot handle multiple batches at a time. For this, there are multiple options:

    • Manually split the input on lines starting with GO (caveat: GO can be called like GO 5, for example, to execute the previous batch 5 times).
    • Use the ManagedBatchParser class/library to help you split the input into single batches, especially implement ICommandExecutor.ProcessBatch with the code above (or something resembling it).

    I choose the later option, which was quite some work, given that it is not pretty well documented and examples are rare (google a bit, you’ll find some stuff, or use reflector to see how the SMO-Assemblies use that class).

    The benefit (and maybe burden) of using the ManagedBatchParser is, that it will also parse all other constructs of T-SQL scripts (intended for SQLCMD.EXE) for you. Including: :setvar, :connect, :quit, etc. You don’t have to implement the respective ICommandExecutor members, if your scripts don’t use them, of course. But mind you that you’ll may not be able to execute “arbitrary” scripts.

    Well, were did that put you. From the “simple question” of how to print “… rows affected” to the fact that it is not trivial to do in a robust and general manner (given the background work required). YMMV, good luck.

    Update on ManagedBatchParser Usage

    There seems to be no good documenation or example about how to implement IBatchSource, here is what I went with.

    internal abstract class BatchSource : IBatchSource
    {
        private string m_content;
    
        public void Populate()
        {
            m_content = GetContent();
        }
    
        public void Reset()
        {
            m_content = null;
        }
    
        protected abstract string GetContent();
    
        public ParserAction GetMoreData(ref string str)
        {
            str = null;
    
            if (m_content != null)
            {
                str = m_content;
                m_content = null;
            }
    
            return ParserAction.Continue;
        }
    }
    
    internal class FileBatchSource : BatchSource
    {
        private readonly string m_fileName;
    
        public FileBatchSource(string fileName)
        {
            m_fileName = fileName;
        }
    
        protected override string GetContent()
        {
            return File.ReadAllText(m_fileName);
        }
    }
    
    internal class StatementBatchSource : BatchSource
    {
        private readonly string m_statement;
    
        public StatementBatchSource(string statement)
        {
            m_statement = statement;
        }
    
        protected override string GetContent()
        {
            return m_statement;
        }
    }
    

    And this is how you would use it:

    var source = new StatementBatchSource("SELECT GETUTCDATE()");
    source.Populate();
    
    var parser = new Parser(); 
    parser.SetBatchSource(source);
    /* other parser.Set*() calls */
    
    parser.Parse();
    

    Note that both implementations, either for direct statements (StatementBatchSource) or for a file (FileBatchSource) have the problem that they read the complete text at once
    into memory. I had one case where that blew up, having a huge(!) script with gazillions of generated INSERT statements. Even though I don’t think that is a practical issue, SQLCMD.EXE could handle it. But for the life of me, I couldn’t figure out how exactly,
    you would need to form the chunks returned for IBatchParser.GetContent() so that the
    parser can still work with them (it looks like they would need to be complete statements,
    which would sort of defeat the purpose of the parse in the first place…).

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I'm working through the NerdDinner MVC tutorial and came across this and was wondering
I came across this Linq to Sql code in an application I am maintaining:
I came across this problem when I want to check what I input is
I came across this situation while migrating our DB from Foxpro to SQL. Below
Problem: I was following this tutorial when I came across a problem. It appears
I was reading the ctypes tutorial, and I came across this: s = Hello,
Came across this error when trying out the ruby on rails tutorial section with
I was doing a Junit tutorial and I came across this normalize function that
I was reading a tutorial on Java logging and came across this line Handler
Working through a tutorial (Professional ASP.NET MVC - Nerd Dinner), I came across this

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.