2010-08-03 61 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