解析SQL查询并提取列名和表名

问题描述 投票:0回答:4

我有一个这样的查询脚本:

SELECT View1.OrderDate,View1.Email,SUM(View1.TotalPayments) FROM dbo.View1
WHERE (View1.OrderStatus = 'Completed') 
GROUP BY View1.OrderDate,View1.Email
HAVING
(SUM(View1.TotalPayments) > 75);

有什么方法可以从SQL查询中提取一些关键信息吗?比如表名和列名,我有2个问题:

  1. 我做了搜索,我找到了一些解析器,比如 ANTLR ,但我找不到 查找说明使用 C# 语言使用此解析器的文档。
  2. 有什么方法可以使用 Entity Frame Work 来解析 sql 查询吗?我的查询是完全动态的,它们是在运行时创建的
c# sql parsing antlr
4个回答
4
投票

我认为最好的答案是使用 Irony 解析器: http://irony.codeplex.com/

Hanselman 有一个关于如何使用它来解析 SQL 的很好的链接: http://www.hanselman.com/blog/TheWeeklySourceCode59AnOpenSourceTreasureIronyNETLanguageImplementationKit.aspx

希望这对您有所帮助,祝您好运!


1
投票

您可以使用一些系统表来获取您正在寻找的信息。

select p.name ParentTable, r.name ReferencedTable, k.name KeyName
from sys.foreign_keys k
join sys.tables p on k.parent_object_id = p.object_id
join sys.tables r on k.referenced_object_id = r.object_id

根据数据库的一致性,您可以假设密钥名称是什么。因此,如果引用表是 [User],您可以假设您正在引用 UserId,如果您的表中有多个键,这将不是您正在寻找的答案。


0
投票

可以使用 SQLParser“Carbunql”检索和编辑元素。

https://github.com/mk3008/Carbunql

样品

下面是获取列名和表名的例子

using Carbunql;

var sq = new SelectQuery(@"SELECT View1.OrderDate,View1.Email,SUM(View1.TotalPayments) FROM dbo.View1
WHERE (View1.OrderStatus = 'Completed') 
GROUP BY View1.OrderDate,View1.Email
HAVING
(SUM(View1.TotalPayments) > 75);");

Console.WriteLine("columns");
sq.SelectClause!.Items.ForEach(item =>
{
    if (string.IsNullOrEmpty(item.Alias))
    {
        //If there is no alias name, return the command
        Console.WriteLine("    " + item.ToOneLineCommand().CommandText);
    }
    else
    {
        Console.WriteLine("    " + item.Alias);
    }
});

Console.WriteLine("table");
var table = sq.FromClause!.Root;
if (string.IsNullOrEmpty(table.Alias))
{
    Console.WriteLine("    " + table.ToOneLineCommand().CommandText);
}
else
{
    Console.WriteLine("    " + table.ToOneLineCommand().CommandText + " as " + table.Alias);
}

结果

columns
    OrderDate
    Email
    SUM(View1.TotalPayments)
table
    dbo.View1 as View1

备注

  • 第三列是函数,没有别名,所以没有列名
  • 获取表名比较麻烦(因为FROM子句还可以指定子查询)

-1
投票

您可以像这样在实体框架中构建动态查询

If(case1)
{
    var query = db.x.where(x => x).toList();
}
else
{
   var query = db.x.where(y => y).toList()
}
© www.soinside.com 2019 - 2024. All rights reserved.