Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/282.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在TSql110Parser解析树中识别T-SQL保留/词汇词_C#_Sql Server_Parsing - Fatal编程技术网

C# 在TSql110Parser解析树中识别T-SQL保留/词汇词

C# 在TSql110Parser解析树中识别T-SQL保留/词汇词,c#,sql-server,parsing,C#,Sql Server,Parsing,我正在使用TSql110Parser列出特定T-SQL过程(最终包括所有模块)中的标识符和QuoteIdentifier令牌。任务是汇总每个模块中使用的列及其表的列表,以便我们能够在脚本的基础上识别数据库中过时的列、表和模块 我已经验证了我的数据库中没有用户对象使用当前定义的T-SQL保留字作为对象名 问题是:是否有一种方法可以检测标识符何时是T-SQL词典的一部分?也就是说,从树.ScriptTokenStream[idx]中包含的信息,可以确定树.ScriptTokenStream[idx]

我正在使用TSql110Parser列出特定T-SQL过程(最终包括所有模块)中的标识符和QuoteIdentifier令牌。任务是汇总每个模块中使用的列及其表的列表,以便我们能够在脚本的基础上识别数据库中过时的列、表和模块

我已经验证了我的数据库中没有用户对象使用当前定义的T-SQL保留字作为对象名

问题是:是否有一种方法可以检测标识符何时是T-SQL词典的一部分?也就是说,从
树.ScriptTokenStream[idx]
中包含的信息,可以确定
树.ScriptTokenStream[idx].Text
是否是T-SQL词汇词吗?所有单词似乎都有一个“tree.ScriptTokenStream[idx].TokenType”而不是“Identifier”,因此它们已经被排除在外。我想要消除的单词是“NOCOUNT”、“VARCHAR”、“LTRIM”和“RTRIM”,它们都有TokenType“Identifier”

相关奖励问题:此列表当前输出到控制台。在SQL Server CLR中将令牌输出重新路由到CRLF分隔文本有什么提示吗

我是一个C#方面的新手,但是已经编写了很长时间了,所以从C#语法的角度来看,你能提供的任何帮助都需要非常低级的

我的环境是VS10/.NET 4.5.2中的SQL Server 2008R2/C

谢谢你的关注和帮助

节目如下:

  // Program.cs
  // Cloned and kludged from Program.cs, found in the BasicUsage project, available from the Samples download link in 
  //   http://blogs.msdn.com/b/arvindsh/archive/2013/11/06/slides-and-samples-for-my-sql-pass-scriptdom-talk.aspx
  //
  // See also: http://michaeljswart.com/2014/04/removing-comments-from-sql/
  // 
  // The page that VS10 "Help" should reference instead of the useless one it does:
  // https://msdn.microsoft.com/en-us/library/kx37x362(v=vs.100).aspx


  using System;
  using System.Collections.Generic;
  using System.Linq;
  using System.Text;
  using System.IO;
  using Microsoft.SqlServer.TransactSql.ScriptDom;

  namespace BasicUsage
  {
      class Program
      {
          static void Main(string[] args)
          {
              // before proceeding, add a reference to the ScriptDom assembly

              IList<ParseError> errors = null;

              //TextReader rdr = new StreamReader(@"C:\ScriptDom\SampleProc.sql");
              TextReader rdr = new StreamReader(@"C:\ScriptDom\pTestProc.sql");

              // pass the reader to the scriptdom
              TSql110Parser parser = new TSql110Parser(true);
              TSqlFragment tree = parser.Parse(rdr, out errors);

              // some placeholders to avoid typing!
              foreach (ParseError err in errors)
              {
                  Console.WriteLine(err.Message);
              }

              string strtokentype ;
              string strtokentext ;
              int strtokentextlen ;
              int tokencount;
              int identifiercount = 0;

              tokencount = tree.ScriptTokenStream.Count;  // 249

              Console.WriteLine(tree.ScriptTokenStream.Count);
              Console.WriteLine("====== Listing only Identifiers ======");

              // walk through the tokens
              int idx = 0;
              for (idx=0; idx < tokencount; idx++ )  // remember: zero-based arrays here.
              {
                  //if (String.Equals(tree.ScriptTokenStream[idx].TokenType, "QuotedIdentifier", StringComparison.OrdinalIgnoreCase) = true ||
                  //    String.Equals(tree.ScriptTokenStream[idx].TokenType, "Identifier", StringComparison.OrdinalIgnoreCase) = true)

                  // Make string ops easier by doing the conversion only once, and operating on a string basis thereafter.
                  strtokentype = Convert.ToString(tree.ScriptTokenStream[idx].TokenType);


                  // if it's a quoted identifier, remove the first and last character, e.g. "[Rate]" becomes "Rate".
                  if (strtokentype == "QuotedIdentifier" ||
                      strtokentype == "Identifier"
                     )
                  {
                      identifiercount++;

                      // do the conversion first,
                      strtokentext =  Convert.ToString(tree.ScriptTokenStream[idx].Text);

                      // then extract the meaningful part if needed.
                      if (strtokentype == "QuotedIdentifier")
                      {
                          strtokentextlen = strtokentext.Length - 2;
                          strtokentext = strtokentext.Substring(1, strtokentextlen);
                      }
                      else
                      {
                          strtokentype = "      Identifier";  // Provide leading spaces to clean up the output text for a nicer presentation.
                      }

                      Console.Write("[" + idx + "] = " + strtokentype);
                      Console.WriteLine("  " + strtokentext);
                      Console.WriteLine();

                  }
              };
              Console.WriteLine();
              Console.WriteLine(identifiercount + "  Identifiers found.");
              Console.WriteLine();

              rdr.Dispose();  // Set breakpoint here so console remains visible during development
          }
      }
  }
//Program.cs
//从Program.cs克隆和克隆,可在BasicUsage项目中找到,可从中的示例下载链接获得
//   http://blogs.msdn.com/b/arvindsh/archive/2013/11/06/slides-and-samples-for-my-sql-pass-scriptdom-talk.aspx
//
//另见:http://michaeljswart.com/2014/04/removing-comments-from-sql/
// 
//VS10“帮助”应该引用的页面,而不是它所引用的无用页面:
// https://msdn.microsoft.com/en-us/library/kx37x362(v=vs.100).aspx
使用制度;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.IO;
使用Microsoft.SqlServer.Transact-SQL.ScriptDom;
命名空间基本年龄
{
班级计划
{
静态void Main(字符串[]参数)
{
//继续之前,请添加对ScriptDom程序集的引用
IList错误=null;
//TextReader rdr=新的StreamReader(@“C:\ScriptDom\SampleProc.sql”);
TextReader rdr=新的StreamReader(@“C:\ScriptDom\pTestProc.sql”);
//将读取器传递给scriptdom
TSql110Parser=新的TSql110Parser(true);
TSqlFragment tree=parser.Parse(rdr,out错误);
//一些占位符,以避免键入!
foreach(ParseError-in-errors)
{
控制台写入线(错误消息);
}
字符串strokentype;
字符串strokentext;
int STROTOKENTEXTLEN;
整数计数;
int identifiercount=0;
tokencount=tree.ScriptTokenStream.Count;//249
WriteLine(tree.ScriptTokenStream.Count);
Console.WriteLine(“=======仅列出标识符=====”;
//浏览代币
int-idx=0;
for(idx=0;idx
事实证明,我所问的MVP一致认为,t-SQL关键字确实没有一个完整的列表

但是,在安装SSMS时会创建包含许多关键字的XML文件。该文件位于计算机上的
C:\Program Files(x86)\Microsoft SQL Server\120\Tools\Binn\ManagementStudio\SqlToolsData\1033\SqlCommonObjects.xml


这些字与保留字(见上述问题中的链接)组合在一起,构成了一个超过