7

プログラムで作成された SQL 列の名前を検証する必要があります...

2 つの検証ルールがあります。

  1. 名前は C# キーワードであってはなりません
  2. 名前は SQL キーワードであってはなりません(SQL Server 2008 R2)

最初のルールの解決策は素晴らしいです:

CSharpCodeProviderクラスには、検証の実装を容易にする IsValidIdentifier メソッドがあります

(元:

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

)


2番目のルールの解決策は少し冗長です:

Google検索を行う唯一の方法は、MSDNからキーワードを取得することです-予約済みキーワード(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 番目の検証ルールの実装について教えてください。それは良い習慣ですか?たぶん、グーグルで見つけられなかった別の実装方法が存在する...

4

3 に答える 3

4

予約語は動くターゲットです。dbms がパブリック インターフェイスを介してそれらを公開しない場合、通常、それらに到達するための適切なプログラムによる方法はありません。

それらを括弧で保護したくない場合は、現在使用している SQL Server のバージョンでは予約されていないが、将来のバージョンでは予約されているシンボルを組み込むリスクがあります

まさにこの問題に対処するように設計されているため、dbms が提供する引用メカニズムを使用するのが最善の策だと思います。SQL Server の場合、これは角かっこを意味します。

于 2013-02-18T15:44:31.543 に答える
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");
   }   
}

これは、Contains を使用した場合の HashSet の速度を示す (@theburningmonk による) 素晴らしい記事です。

(クリックしたくない人のために、HashSetはゼロです)

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

于 2013-02-18T16:00:59.100 に答える
1

一般的に、アプローチは正しいように見えます。特定の言語のキーワードを取得するには、文書化されていないものがあるため、(できれば小さな) 少しの試行錯誤が必要ですが、主な情報源は常に言語仕様自体です。独自のバリデーターを備えた言語は知りませんが、存在しないわけではありません。

Visual Studio 自体には、特定の言語の検証を行うのに役立つ一連の xml ファイルがあります。IDE を開発している場合、次のようなテーブルがあるかもしれません。

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

…お分かりですね。あなたの場合、例外をスローしないように、考えられる問題のキーワードを除外したいだけです。例外のスローを許可し、それを具体的にキャッチして処理すること、あまりクリーンではありませんが有効な方法です。

あなたのケースに関しては、私が行う唯一の実際の調整は、コンパイル時にキーワードのリストをプログラムに埋め込むのではなく、アプリケーションの開始点でロードされる外部ファイルにリストを保存することです。これにより、何かを忘れた場合や、アプリケーションの再構築を必要とせずに言語の新しいバージョンをサポートする必要がある場合に、ある程度の柔軟性が得られます。

于 2013-02-18T15:37:46.323 に答える