5

我有一个包含 sql 命令的字符串,

像这样的东西:

strCommand = "Select [Feild1], [Feild2] From TableName Order By [Feild1] 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 Server 为您完成解析查询的艰苦工作,而不是尝试考虑 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

这是为我们提供表名的方法,只需更改 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 回答
1

您可以使用子字符串(这样,您必须选择多少列都没有关系)

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

ISun 的回答满足了我的需求,但需要进行一项更改才能获取表名:

string table = strCommand.ToLower().Substring(strCommand.IndexOf("FROM".ToLower())).Split(' ')[1];

不是

string table = strCommand.ToLower().Substring(strCommand.IndexOf("FROM".ToLower())).Split(' ')[0];
于 2017-06-22T20:03:02.197 回答
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 回答