stoqnvost
  • Posts: 4
  • Joined: 2/13/2013
In SSMS hitting F5 executes the entire script. If the script contains several statements, all will be executed.
To execute one statement from the script I have to first select the statement and then hit F5.

Is it possible to add a new feature to execute only the current statement (according the cursor).

Example:

--[SqlQuery1.sql]
select * from ACTION_LOG
select 
    *
from 
    ACTION_LOG
where
    ACTION_KINE = 'CMD1'
select top 10 * from ACTION_LOG


If I press Ctrl+E (the shortcut for [ExecuteCurrentStatement]) and the cursor is at line 4, the second statement should be executed (lines [3..8])

Thanks in advance.
Andrei
  • Posts: 398
  • Joined: 7/1/2012
Hi ! We had already similar proposal here. The problem is to determine what is "current statement". Such feature will require more or less advanced parsing and could produce unexpected results in some complicated cases.
Implementing it now would block our ressources gratly. Currently it is set on hold, but it can be re-evaluated after we master new Parser library, that is now available with SSMS.
stoqnvost
  • Posts: 4
  • Joined: 2/13/2013
Hi Andrei,

I was fooling around with the DTE interfaces and was able to extract the current statement. Unfortunately didn't find a way to actually execute it.


        public static EnvDTE.TextDocument GetActiveDocument( DTE2 application )
        {
            EnvDTE.TextDocument doc = (EnvDTE.TextDocument)ServiceCache.ExtensibilityModel
                    .Application.ActiveDocument.Object( null );

            return doc;
        }

        public static int GetActivePoint(EnvDTE.TextDocument doc)
        {
            if (doc.Selection.Text.Length != 0)
            {
                return doc.Selection.AnchorPoint.VirtualCharOffset;
            }
            return doc.Selection.ActivePoint.AbsoluteCharOffset;
        }

        public static string GetDocumentScript( EnvDTE.TextDocument doc )
        {
            var query = string.Empty;

            if (doc != null)
            {
                query = doc.Selection.Text;

                if (string.IsNullOrWhiteSpace( query ))
                {
                    var oldAnchor = doc.Selection.AnchorPoint.CreateEditPoint();
                    var oldActivePoint = doc.Selection.ActivePoint.CreateEditPoint();

                    doc.Selection.SelectAll();
                    query = doc.Selection.Text;

                    // respore ActivePoint
                    doc.Selection.MoveToAbsoluteOffset( oldAnchor.AbsoluteCharOffset );
                    doc.Selection.SwapAnchor();
                    doc.Selection.MoveToAbsoluteOffset( oldActivePoint.AbsoluteCharOffset );
                }
            }

            return query;
        }

        public static string GetCurrentStatement( string query, int activePoint )
        {
            var currentStatement = string.Empty;

            TSql100Parser parser = new TSql100Parser( true );
            IList<ParseError> errors;
            StatementList statementList;

            using (StringReader reader = new StringReader( query ))
            {
                statementList = parser.ParseStatementList( reader, out errors );
            }

            if (errors.Count == 0)
            {
                foreach (var statement in statementList.Statements)
                {
                    var firstToken = statement.ScriptTokenStream(statement.FirstTokenIndex);
                    var LastToken = statement.ScriptTokenStream(statement.LastTokenIndex);

                    if (activePoint >= firstToken.Offset && activePoint <= LastToken.Offset + LastToken.Text.Length)
                    {
                        for (var i = statement.FirstTokenIndex; i <= statement.LastTokenIndex; i++)
                        {
                            currentStatement += statement.ScriptTokenStream(i).Text;
                        }
                    }
                }
            }

            return currentStatement;
        }

        public static void Parce(DTE2 application)
        {
            var doc = GetActiveDocument( application );
            var query = GetDocumentScript( doc );
            var activePoint = GetActivePoint( doc );

            var currentStatement = string.Empty;

            if (!string.IsNullOrWhiteSpace( query ))
            {
                currentStatement = GetCurrentStatement( query, activePoint );
                Debug.WriteLine( "*************************" );
                Debug.WriteLine( currentStatement );
                Debug.WriteLine( "*************************" );
            }
        }
Andrei
  • Posts: 398
  • Joined: 7/1/2012
Wow ! That is great, thank you. It makes out life easier: I will check it and get back to you with results. It looks easy now 🙂
stoqnvost
  • Posts: 4
  • Joined: 2/13/2013
Hi, I've made an add-in for SSMS 2012 implementing this feature. You can check it out at https://ssmsexecutor.codeplex.com/ .
If you want, feel free to use the code however you want.
wRatte
  • Posts: 43
  • Joined: 10/25/2012
Wow. Freekin cool way to ask for a feature. (Providing code as well.)
stoqnvost Respect +1.
Andrei
  • Posts: 398
  • Joined: 7/1/2012
Great ! I will have a look at it. We have mastered the parser of SSMS since last release, so I think it will be easy now.
  • You cannot post new topics in this forum.
  • You cannot reply to topics in this forum.
  • You cannot delete your posts in this forum.
  • You cannot edit your posts in this forum.
  • You cannot create polls in this forum.
  • You cannot vote in polls in this forum.