我需要从简单的字符串中提取代表sql查询的查询中使用的表而不在C#中执行查询本身。
示例:
string strQuery = "SELECT * FROM table1 LEFT JOIN (SELECT * FROM table2) tt WHERE tt.name IN (SELECT name FROM table3)";
ArrayList arrUsedTables = GetUsedTablesFromQuery(strQuery);
在此行之后,对象arrUsedTables
将包含:
table1
,table2
,table3
请记住,查询可能会非常复杂!
答案 0 :(得分:3)
无需转到数据库,您无法确定查询中使用的表格的名称。
如果您的查询使用视图或存储过程怎么办?
如果不咨询数据库,这些对消费者来说是透明的。
唯一可以确定的方法是从数据库查询表列表,然后然后尝试从内联sql中解析它们。
答案 1 :(得分:2)
您必须为以下程序集添加引用和指令:
using Microsoft.Data.Schema.ScriptDom;
using Microsoft.Data.Schema.ScriptDom.Sql;
using System.IO;
然后,您可以创建GetUsedTablesFromQuery
方法:
private static ArrayList GetUsedTablesFromQuery(string strQuery)
{
var parser = new TSql100Parser(true);
IList<ParseError> errors = new List<ParseError>();
using (TextReader r = new StringReader(strQuery))
{
var result = parser.GetTokenStream(r, out errors);
var tables = result
.Select((i, index) => (i.TokenType == TSqlTokenType.From) ? result[index + 2].Text : null)
.Where(i => i != null)
.ToArray();
return new ArrayList(tables);
}
}
答案 2 :(得分:0)
您可以使用ANTLR之类的SQL解析器,如this question and answer中所述,以获得SQL的完整解析,然后提取表名。
另一种选择是执行一些原始SQL以获取查询的执行计划(使用指令here)。执行计划采用XML格式,然后您可以使用Linq to XML查询任何Table
标记上所有ColumnReference
属性的计划。