2010-08-03 63 views
1

有什么方法可以获取我在查询中使用的表?在查询中获取mysql表

我用第一种方法是使用正则表达式:

// result[1] = "SELECT" 
// result[3] = "All between FROM and WHERE, ex: `users`, ex: `users`, `test` 

if($result[1] == "SELECT" && !preg_match('/FROM\s*(.*?,.*?)\s*WHERE/i', $query, $res)) 
{ 
    $tables = preg_replace('/`|\'|\s/i', '', $result[3]); // strip ` or ' or spaces 
    $tables = explode(",", $tables); 
    sort($tables); 
} 

但也有复杂的MySQL查询,所以我用下一个方法是:

EXPLAIN SELECT... 

,并从表结果数组。

问题带有计数,我知道,在MyISAM数据DB的行数存储,所以如果你做一个查询:

SELECT COUNT(*) FROM users 

你没有得到所使用的表在查询中,你会得到“选择表优化”,因为使用任何表。

那么,还有另一种方法来获得表中使用的查询

回答

1

我正在做的是使用这两种方法。

private function get_tables($query) 
{ 
    $res = preg_match('/^(SELECT|UPDATE|INSERT|DELETE)(.+?FROM| INTO)?\\s*`?(.+?)($|`| |\\()/i', $query, $result); 

    if(!$res) 
     return false; 

    $tmp_tables = array(); 

    // Get array tables using EXPLAIN 
    if($result[1] == "SELECT") 
     $tmp_tables = $this->get_select_query_tables($query); 

    // Get array tables using REGEX 
    if($result[1] == "SELECT" && !preg_match('/FROM\s*(.*?,.*?)\s*WHERE/i', $query, $res)) 
    { 
     $tables = preg_replace('/`|\'|\s/i', '', $result[3]); 
     $tables = explode(",", $tables); 
     sort($tables); 

     $tmp = $tables; 

     // Check if all REGEX tables are in EXPLAIN tables, if not, add the missed 
     foreach($tmp as $tmp_table) 
      if(!in_array($tmp_table, $tmp_tables)) 
       $tmp_tables[] = $tmp_table; 
    } 

    return $tmp_tables; 
} 
+0

有关连接的查询呢?您还需要扫描这些以获取连接的表名称。对于外键,如果更新/删除级联,也可以隐式地涉及其他表。怎么看?那些可以在后台涉及多个表格,但是将它们表现为单个“表格”。然后触发器......这是一个大蜡球 – 2010-08-04 04:49:15

+0

@Marc乙:我使用的最终解决方案是搜索查询内的所有表。缓存结果,最佳性能。 – Wiliam 2010-08-04 14:06:51

1

如果您在每次提及数据库时都明确地用数据库名称作为前缀,它会使您的RegEx变得更加简单。 :-)你能编辑你的查询吗?

+0

是的,这是一个好主意,但不是我正在寻找的解决方案,我需要的是解析的,所以我将改为MySQLi http://stackoverflow.com/questions/740316/enumerating-tables -used-in-mysql-query – Wiliam 2010-08-03 15:12:03

+0

Mmmmm ...思考你的回应,我可以列出所有表格(缓存)并在查询中搜索它们!这将是一个解决方案:) – Wiliam 2010-08-03 22:43:09