2016-10-05 16 views
0

APIからいくつかのログサービスがあり、クエリがアクセスしているデータベースを捕らえるのに問題があります。文字列から単語を抽出する方法

言って、クエリは次のように来る:私が達成したいのですがどのような

Select Top 10 * From DataBase..Table 

は、「データベース」または以前の「..」の文字列でのテキストを取得することです。

はまた、時々、クエリは次のように来る:

Select Top 10 * From DataBase.Schema.Table 

それは両方のケースで、「データベース」の文字列を取得することはできますか?

ここで私がしようとしてきたことはありますが、私は正規表現でそれほど良くありません。

([A-Z]+\.+?([A-Z])*(\.)+[A-Z]) 

しかし、これは、以下の(角括弧で)一致した:助けのため

Select Top 10 * From [DataBase..T]able 

感謝を!

編集: これはC#で行われ、クエリ/リクエストをデータベースに送信する前に、このAPIメソッドが処理するすべてのリクエストを記録しようとしています。

+3

SQLは複雑な言語であり、正規表現のような直接的な文字列の手法で解析すると危険があります。最も信頼できる方法はSQLパーサを使用することです。あなたの具体的な例題に関する具体的な質問については、キーワード「From」を使用してパターンを開始し、任意の数の空白の後にドットではないすべてのもの(キャプチャグループ内)を取得することをお勧めします。 –

+0

これはc#で行われます。リクエストをキャッチしてデータベースに問い合わせる前にファイルにログインするAPIです。これはSQL Serverで行われていません。申し訳ありませんが、わからない場合は、 –

+0

データベース名には、ドットを含む任意の文字を使用できます。より一般的で素朴な方法は、 "from"と "。"の間で部分文字列を見つけることですが、データベースには[FROM。 ] ' – Slai

答えて

0

コメントに記載されているように、このようにSQLを解析することは、遭遇する複雑さのために悪い考えです。しかし、これがあなたがやりたいことなら、次のように働かなければなりません。 select文またはdelete文では機能しますが、挿入/更新は構造が異なるため動作しません。

public string GetDbName(string sql) 
{ 
    var sqlLower = sql.ToLower(); 
    var parts = sqlLower.Split(new string[] { "from " }, StringSplitOptions.RemoveEmptyEntries); 

    if (parts.Length < 2) 
    { 
     //something is wrong in sql; 
     //may be its not a select statement 
     return null; 
    } 

    var tableName = parts[1] 
     .Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries) 
     .FirstOrDefault(); 

    var posOfTableName = tableName.LastIndexOf('.'); 
    var dbName = tableName.Substring(0, posOfTableName); 

    //We can return here, but it will return lower case db name parts 
    //We can also get the original value as well by looking into original parameter 
    var indexOfStart = sqlLower.IndexOf(dbName); 
    return sql.Substring(indexOfStart, dbName.Length); 

} 
+0

私はこのATMと非常によく似た何かを使用していますが、文字列とその他のものを分割する手間がなくてもこれを実現するためのREGEXがあるのだろうかと思います。ありがとう! –

関連する問題