是获取SQL关键字的程序化方法(保留字)

时间:2013-02-18 15:29:14

标签: c# sql sql-server-2008 keyword reserved-words

我需要验证SQL列的名称,这是以编程方式创建的......

应该有2个验证规则:

  1. 名称不应是C#关键字
  2. 名称不应是SQL关键字(SQL Server 2008 R2)

  3. 第一条规则的解决方案很不错:

    CSharpCodeProvider 类具有 IsValidIdentifier 方法,可以轻松实现验证。

    (例如:

    string myColumnName = "blabla";
    var isValid = _cSharpCodeProvider.IsValidIdentifier(myColumnName);
    


    第二条规则的解决方案很简单:

    我发现进行Google搜索的唯一方法是从MSDN - Reserved Keywords (Transact-SQL) SQL Server 2008 R2

    中获取关键字

    构建一个string []属性,它将返回所有这些关键字......

    (例如:

    public static class SqlReservedKeywords {
    
         public static string[] SqlServerReservedKeywords {
            get { return SqlServerKeywords; }
         }
    
         private static readonly string[] SqlServerKeywords = new[] { 
            "ADD","EXISTS","PRECISION",   
    
        //. . .
    
            "EXEC","PIVOT","WITH",
            "EXECUTE","PLAN","WRITETEXT"
         };
    }
    

    //外部代码

    var isValid = SqlReservedKeywords.SqlServerReservedKeywords.Contains(myColumnName);
    


    您能否就第2次验证规则的实施向我提出建议。 这是一个好习惯吗? 也许它存在另一种方式来实现我没有通过谷歌搜索找到...

3 个答案:

答案 0 :(得分:4)

保留字是移动目标。如果dbms没有通过公共接口公开它们,那么通常没有良好的编程方式来访问它们。

如果您不想使用括号来保护它们,则可能会在当前使用的SQL Server版本中包含未保留的符号,但在将来的某个版本中 保留。

我认为最好的办法是使用dbms提供的引用机制,因为它旨在解决这个问题。对于SQL Server,这意味着方括号。

答案 1 :(得分:3)

由于有一个函数可以调用C#,真正的问题是如何查找SQL保留字。你在这里实现查看的方式并不是最有效的C#。您应该使用HashSet - 快速未经测试的代码示例如下:

public static class SqlReservedKeywords {

   public bool isReserved(string in)
   {
      return SqlServerKeywords.Contains(in.ToUpper());
   }

   private static HashSet<string> SqlServerKeywords = new HashSet<string>();

   static SqlReservedKeywords() 
   {
      SqlServerKeywords.Add("ADD");
      SqlServerKeywords.Add("EXISTS");
      SqlServerKeywords.Add("PRECISION");

   //. . .

      SqlServerKeywords.Add("EXEC");
      SqlServerKeywords.Add("PIVOT");
      SqlServerKeywords.Add("WITH");
      SqlServerKeywords.Add("EXECUTE");
      SqlServerKeywords.Add("PLAN");
      SqlServerKeywords.Add("WRITETEXT");
   }   
}

这是一篇很好的文章(@theburningmonk),展示了使用Contains时HashSet的速度有多快

(对于那些不想点击的人,HashSet为零)

http://theburningmonk.com/2011/03/hashset-vs-list-vs-dictionary/

答案 2 :(得分:1)

通常,该方法看起来是正确的。获取任何给定语言的关键字涉及(由于任何未记录的事情而导致的试验和错误),但主要来源始终是语言规范本身。我不知道任何自带验证器的语言,但并不是说它们不存在。

Visual Studio本身有一组xml文件,可帮助它对任何给定语言进行验证。如果您正在开发IDE,那么您可能会有一个类似于

的表
Keyword     | MatchWithRegEx | Color
------------+----------------+---------
for         | \wfor          | #FF0000

...你明白了。在您的情况下,您只想过滤掉可能的问题关键字,以便它们不会抛出异常。允许抛出异常并捕获并专门处理 是一种有效的方法,虽然不是很干净。

至于你的情况,我所做的唯一真正的调整是在编译时没有将关键字列表隐藏到程序中,而是将列表存储在外部文件中,该文件在应用程序的起始点加载。如果您忘记了任何内容或需要支持语言的更高版本而无需重新构建应用程序,则可以提供一些灵活性。