我需要一个Regex语句(在c#中运行),它将包含一个包含Sql Update语句的字符串作为输入,并返回一个要更新的列列表。它应该能够处理括号或不包围的列。
// Example Sql Statement
Update Employees
Set FirstName = 'Jim', [LastName] = 'Smith', CodeNum = codes.Num
From Employees as em
Join CodeNumbers as codes on codes.EmployeeID = em.EmployeeID
最后我想要返回包含以下内容的IEnumerable或List:
任何人对实施有什么好的建议吗?
更新:sql是用户生成的,所以我必须按原样解析Sql。在我的情况下,提取列名称的目的是验证用户是否有权更新查询中包含的列。
答案 0 :(得分:3)
你正在倒退。以分解的形式存储数据,包括要更新的表,列名和表达式,以便单独生成新值。从这个规范表示中,生成SQL(当您需要它时)和要更新的列列表(当您需要它时)。
如果绝对必须从SQL语句中提取列名,我认为正则表达式不是正确的方法。例如,在一般情况下,您可能需要跳过包含任意嵌套括号的新值表达式。您可能需要一个完整的SQL解析器。这本书 Lex& Levine,Mason和Brown的Yacc 有一章解析SQL。
对更新的回应: 你是一个受伤的世界。执行所需操作的唯一方法是完全解析SQL,因为您还需要确保没有任何执行未授权操作的子表达式。
我非常非常强烈地建议你想出另一种方法去做你正在做的事情。也许可以将可修改的字段分成单独的表并使用访问控制?也许想出另一个界面供他们用来指定他们想要做什么?无论你正在做什么,几乎可以肯定有更好的方法。在那条路上有龙。
答案 1 :(得分:2)
正则表达式无法执行此任务,因为SQL不是regular language。
您可以执行此操作,但不能使用正则表达式。你需要一个完整的解析器。
您可以使用ANTLR在C#中生成解析器,并且有免费的语法available用于在ANTLR中解析SQL。
但是,我同意Glomek允许用户提供的SQL针对您的系统运行,即使您尝试验证它不包含“未经授权的操作”,也是愚蠢的。有太多案例可能会绕过您的验证。
相反,如果您只有一个文本字段,则应定义一个简化的Domain-Specific Language,允许用户仅指定他们有权执行的操作。通过此输入,您可以自己构建SQL。
答案 2 :(得分:0)
SQL有一个复杂的递归语法,并且总会有一些sub select,group by或literal会破坏你的基于正则表达式的解析器。
为什么不使用sql解析器来实现你所需要的,这里是an article向你展示如何在3分钟内实现你需要的东西。