5

SQLコマンドを含む文字列があり、

このようなもの:

strCommand = "テーブル名から [フィールド 1]、[フィールド 2] を選択 [フィールド 1] desc で並べ替え" ;

この文字列でテーブル名を見つけるにはどうすればよいですか?

4

7 に答える 7

6

これまでの解決策はすべて、文字列内の検索アプローチを使用していました。SQL クエリが常に同じように見えるかどうかについては言及していませんが、これらのソリューションが壊れるクエリには多くのバリエーションがあります。検討...

  • SELECT Field1, Field2 FROM TableName
  • SELECT Field1, Field2 FROM [TableName]
  • SELECT Field1, Field2 FROM dbo.TableName
  • SELECT Field1, Field2 FROM Table1Name, Table2Name

解析しようとしているクエリがデータベースを持っているクエリである場合、SQL ですべてのケースを説明しようとする代わりに、SQL サーバーにクエリを解析するという大変な作業をさせることができます。を使用してクエリを実行するSET SHOWPLAN_ALL ONと、クエリ プランのテーブルが生成されます。その後、Arguments 列を分析できます。この列には、クエリに含まれるすべてのフィールドが標準形式で含まれています。プログラムの例を以下に示します。

SqlConnection conn = new SqlConnection(CONNECTIONSTRING);
conn.Open();

SqlCommand cmd = conn.CreateCommand();
cmd.CommandText = "SET SHOWPLAN_ALL ON";
cmd.ExecuteNonQuery();
cmd.CommandText = "SELECT [Field1], [Field2] FROM [TableName]";

DataTable dt = new DataTable();
dt.Load(cmd.ExecuteReader());

Regex objectRegex = new Regex(@"^OBJECT:\(\[(?<database>[^\]]+)\]\.\[(?<schema>[^\]]+)\]\.\[(?<table>[^\]]+)\]\.\[(?<field>[^\]]+)\]\)$", RegexOptions.ExplicitCapture);

List<string> lstTables = new List<string>();
foreach (DataRow row in dt.Rows)
{
    string argument = row["Argument"].ToString();
    if (!String.IsNullOrEmpty(argument))
    {
        Match m = objectRegex.Match(argument);
        if (m.Success)
        {
            string table = m.Groups["schema"] + "." + m.Groups["table"];
            if (!lstTables.Contains(table))
            {
                lstTables.Add(table);
            }
        }
    }
}

Console.WriteLine("Query uses the following tables: " + String.Join(", ", lstTables));

これは、クエリ名のすべての形式を処理し、含まれている方法に関係なく、クエリに含まれるすべてのテーブルを返します。

于 2012-06-09T08:30:53.693 に答える
2

これが常に同じパターンである場合:

 string tableName = strCommand.Split(' ', strCommand)[4];

ただし、フィールドを追加/削除できる場合は、分割された文字列を繰り返し処理して「From」を検索すると、次の文字列がテーブル名になります

于 2012-06-09T07:25:44.880 に答える
1

テーブル名を取得するためのより信頼性の高い方法として、「From」の後にあるものを言います。作成された配列をループし、「From」に到達すると、次の配列がテーブルになります。

于 2012-06-09T07:27:17.323 に答える
1

部分文字列を使用できます(この方法では、選択する必要がある列の数は関係ありません)

string table = strCommand.ToLower().Substring(strCommand.IndexOf("FROM".ToLower())).Split(' ')[0];
于 2012-06-09T07:52:16.477 に答える
1

これは、SQLクエリ文字列、接続文字列を変更するだけでテーブル名を与えるメソッドです

単純なクエリで動作し、結合も可能

public static List<string> getTablenames(string connString, string QueryString)
{
    SqlConnection con = new SqlConnection(connString);
    con.Open();
    DataTable dt = con.GetSchema("Tables");

    List<string> getTableName = new List<string>();
    List<string> tablenames = new List<string>();

    foreach (DataRow dr in dt.Rows)
       tablenames.Add(dr[2].ToString());

    for (int i = 0; i < dt.Rows.Count; i++)
    {
        string myTable = tablenames[i];
        Boolean checkMyTable = QueryString.Contains(myTable);
        if (checkMyTable == true)
            getTableName.Add(myTable);
    }
    con.Close();
    return getTableName;
}
于 2012-06-09T07:38:37.730 に答える
0

SQLで解決策が必要な場合は、これを試してください

declare @q varchar(1000) = 'Select [Feild1], [Feild2] From TableName Order By [Feild1] desc',
        @tableName varchar(100) = '',
        @temp varchar(1000),
        @temp2 char(1)

declare @frmIndex int = CHARINDEX('From', @q, 0);
declare @flag int = 0, @counter int = 1;
select @temp = SUBSTRING(@q, @frmIndex, len(@q))

set @temp = LTRIM(REPLACE(@temp,'From',''))

while(@flag <> 1)
begin
    set @temp2 = SUBSTRING(@temp, @counter, 1)
    if(@temp2 = ' ')
        set @flag = 1
    select @tableName = @tableName + @temp2
    set @counter = @counter + 1
end

select @tableName as TableName
于 2012-06-09T08:04:38.107 に答える