如何从包含SELECT语句的字符串中获取表名

时间:2012-06-09 07:22:07

标签: c# sql-server string

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

类似的东西:

  

strCommand =“选择[Feild1],   [Feild2]   来自TableName   订购[Feild1] desc“;

如何在此字符串中找到表名?

7 个答案:

答案 0 :(得分:5)

到目前为止,解决方案都采用字符串搜索方式。您没有提到您的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));

这将处理所有形式的查询名称,并返回查询中涉及的所有表,无论它们如何包含在内。

答案 1 :(得分:2)

如果这是一直相同的模式:

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

但是如果您可以添加/删除字段只是遍历拆分字符串并搜索“From”,则下一个字符串将是您的表名

答案 2 :(得分:1)

我会说 - 在“From”之后是什么,以获得表名更可靠的方式。循环创建的数组,当你到达“From”时,下一个就是表格。

答案 3 :(得分:1)

这是方法,它给我们tablename只需更改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;
}

答案 4 :(得分:1)

您可以使用子字符串(这样,您必须选择多少列无关紧要)

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

答案 5 :(得分:1)

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

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

不是

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

答案 6 :(得分: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