首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何使用DacFX注释TsqlFragment/TSqlScript中的语句

如何使用DacFX注释TsqlFragment/TSqlScript中的语句
EN

Stack Overflow用户
提问于 2018-03-08 17:09:36
回答 2查看 323关注 0票数 0

如果我有一个带有一组语句的TqlFragment或TsqlScript,如何使用DacFX注释特定的语句?没有CommentStatement或类似的东西。如何将语法树中的语句替换为注释版本的语句?

我知道这可以通过纯文本编辑或regex来完成,但此时我正在使用DacFx访问者模式扫描某些语句。所以我需要继续使用这个约束。

EN

Stack Overflow用户

发布于 2018-03-12 16:48:49

艾德,我重新整理了你的答案。

  • 修改访问者以处理多个语句
  • 更改代码,使其在访问者语句中向后循环,这样就不会损坏位置。
  • 修改代码以插入注释标记

意见:

  • 正如您推断的那样,sql生成器在试图写出令牌流时愉快地删除了注释。
  • 以这种方式添加注释将注释中行尾的分号排除在外。

代码:

代码语言:javascript
运行
复制
class Program
{
    static void Main(string[] args)
    {
        var sqlText = @"
create procedure something
as
    select 100;
    select 200

    exec sp_who;              

    exec sp_who2;              
";

        var sql = new StringReader(sqlText);

        var parser = new TSql140Parser(false);
        var script = parser.Parse(sql, out IList<ParseError> errors);

        var visitor = new ExecVisitor();
        script.Accept(visitor);

        TSqlParserToken startComment = new TSqlParserToken(TSqlTokenType.SingleLineComment, "/*");
        TSqlParserToken endComment = new TSqlParserToken(TSqlTokenType.SingleLineComment, "*/");

        var newScriptTokenStream = new List<TSqlParserToken>(script.ScriptTokenStream);

        for(var i = visitor.Statements.Count - 1; i >= 0; i--)
        {
            var stmt = visitor.Statements[i];
            newScriptTokenStream.Insert(stmt.LastTokenIndex, endComment);
            newScriptTokenStream.Insert(stmt.FirstTokenIndex, startComment);
        }
        var newFragment = parser.Parse(newScriptTokenStream, out errors);
        Console.WriteLine(GetScript(newFragment.ScriptTokenStream));
    }

    private static string GetScript(IList<TSqlParserToken> tokenStream)
    {
        var sb = new StringBuilder();
        foreach(var t in tokenStream)
        {
            sb.Append(t.Text);
        }

        return sb.ToString();
    }
}

class ExecVisitor : TSqlFragmentVisitor
{
    public IList<ExecuteStatement> Statements { get; set; } = new List<ExecuteStatement>();
    public override void Visit(ExecuteStatement s)
    {
        Statements.Add(s);
    }
}

结果:

代码语言:javascript
运行
复制
create procedure something
as
        select 100;
        select 200

        /*exec sp_who*/;

        /*exec sp_who2*/;
票数 1
EN
查看全部 2 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49178729

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档