2009-01-14 133 views
1

我需要一个正则表达式(在c#中运行),它将包含Sql Update语句的字符串作为输入,并将返回要更新的列的列表。它应该能够处理括号或不括号的列。从SQL语句中提取更新列的正则表达式

// 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或含列表:

  1. 名字
  2. CodeNum

任何人有执行什么好的建议?

更新:sql是用户生成的,所以我必须解析Sql,因为它是给定的。在我的情况下提取列名的目的是验证用户有权更新查询中包含的列。

回答

3

你正在做倒退。将数据以分解形式存储,并更新表格,列名称和表达式以生成全部分开的新值。从这个规范表示中,生成SQL(当你需要它时)和列更新列(当你需要时)。

如果您绝对必须从SQL语句中取出列名称,我不认为正则表达式是正确的方式。例如,在一般情况下,您可能需要跳过包含任意嵌套括号的新值表达式。您可能需要一个完整的SQL解析器。 The book Lex & Yacc作者:Levine,Mason和Brown撰写了关于解析SQL的章节。

回复更新: 你是为了一个受伤的世界。做你想做的事情的唯一方法是完全解析SQL,因为你还需要确保你没有任何执行未授权操作的子表达式。

我非常非常强烈地建议您想出另一种方法去做任何你正在做的事情。也许可以将可修改的字段分解为单独的表并使用访问控制?也许想出另一个界面供他们用来指定他们想做什么?无论你在做什么,几乎肯定有更好的方法来做到这一点。在那条路上有龙。

+0

我绝对必须把我们的sql语句的列名称(请参阅上面的更新)。 为什么你不认为正则表达式是要走的路?我不是仅仅匹配在查询中的单词SET后面开始的以逗号分隔的“=”语句的左边部分吗? – 2009-01-14 18:44:49

+0

我的回复太长而无法发表评论,所以我把它作为上面的修改。 – Glomek 2009-01-14 18:55:52

2

正则表达式无法完成此任务,因为SQL不是regular language

你可以这样做,但不能用正则表达式。你需要一个全面的解析器。

您可以使用ANTLR在C#中生成解析器,并且有用于解析ANTLR中的SQL的免费文法available

但是,我同意Glomek允许用户提供的SQL针对您的系统运行,即使在您尝试验证它没有包含“未经授权的操作”后,也是愚蠢的。有太多情况可能会绕过你的验证。

相反,如果您只有一个文本字段,则应该定义一个简化的Domain-Specific Language,它允许用户只指定他们有权执行的操作。从这个输入中,你可以自己构建SQL。

0

SQL有一个复杂的递归语法,并且总会有一些子选择,分组依据或文字,这些会破坏基于正则表达式的解析器。

为什么不使用sql语法分析器来实现你所需要的,这里是an article向你展示了如何在3分钟内达到你所需要的。