【问题标题】:Find if a word in an SQL query is in a subquery查找 SQL 查询中的单词是否在子查询中
【发布时间】:2012-09-29 23:33:15
【问题描述】:

我需要一种方法来搜索 SQL 查询中的单词,并能够确定该单词是在子查询中还是在主查询中。

例如:

SELECT * 
FROM products 
WHERE id NOT IN (SELECT product_id 
                 FROM tagmap 
                 WHERE tag_id = 1)

我需要在查询字符串中将单词WHERE 的实例替换为WHERE 1=1 AND,但仅限于主查询中,而不是子查询中。

这只是我面临的问题的一个例子。真正的查询比这大得多,并且包含几个子查询!此外,我需要为数百个查询执行此操作,因此我需要能够自动执行此操作。

【问题讨论】:

  • 只要WHERE 不在( .. ) 中,您是否只需将WHERE 的任何实例替换为WHERE 1=1 AND 即可?您是否需要在文本/查询编辑器中执行此操作,或者以编程方式通过例如 sql 脚本文件(在这种情况下,哪种语言?)
  • 是的,这就是我要找的。我最好使用文本编辑器来做到这一点。
  • 是否有WHERE 需要替换总是在左边距,而子查询总是缩进?
  • 不,上面的布局只是语法高亮——它通常只是一个内联字符串。

标签: mysql sql regex replace


【解决方案1】:

认为下面的正则表达式:

(?<!\(.*)\b(WHERE)\b|\b(WHERE)\b(?!.*\))

将匹配“WHERE”的任何实例:

  • 出现在第一个括号的左边,或
  • 出现在最后一个括号的右边

ie 不会检测发生在 内部 (..) 的 WHERE 实例。

它在我尝试过的几个测试用例上都有效...如果没有进一步说明您的要求,我不会再做任何测试...

EG 下面,我用波浪号包围表示匹配的实例:~WHERE~

SELECT * 
FROM products 
~WHERE~ id NOT IN 
    (SELECT product_id FROM tagmap WHERE tag_id = 1 and (SELECT true WHERE something) );

SELECT x FROM y ~WHERE~ z = z;

SELECT Count(*) 
FROM (Select rows FROM table WHERE filter) 
~WHERE~ z

强烈建议您在依赖它之前彻底测试它。


编辑:一个基本的 .NET 实现...因为我现在打开了 VS...;-)

using System;
using System.Text;
using System.Text.RegularExpressions;
using System.IO;

class Program
{
    static void Main(string[] args)
    {
        StreamReader sr = new StreamReader("pathToSqlScript.sql");
        string oldSQLString = sr.ReadToEnd();
        string newSQLString = Regex.Replace(oldSQLString, @"(?<!\(.*)\b(WHERE)\b|\b(WHERE)\b(?!.*\))", @"WHERE 1=1 AND");
        StreamWriter sw = new StreamWriter("newSqlScript.sql");
        sw.Write(newSQLString);
    }
}

编辑:在文本编辑器中执行此操作...

Visual Studio 将允许您基于正则表达式执行搜索/替换。我想像 Notepad++ 这样的东西会做到这一点(至少在插件的帮助下)。或者这可能会对您有所帮助:http://www.regular-expressions.info/editpadpro.html

否则,敲一些会读取/修改您的文本文件的东西,例如使用 PHP、.NET、Java ......

【讨论】:

  • 我已经对我的数据样本进行了测试,它运行良好。在完全提交之前,我会进行一次虚拟运行。非常感谢。
猜你喜欢
  • 2021-10-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-08
相关资源
最近更新 更多