2015-05-29 79 views
0

我想使用INFORMATION_SCHEMA修剪數據庫中的表。要測試DELETE我正在使用SELECT來查看數據是否正確返回。我想根據數據庫是否存在從master.company中刪除數據。這就是我試圖和它不工作:爲什麼我不能在子選擇中使用INFORMATION_SCHEMA?

USE DATABASE master; 

CREATE TABLE `company` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `domain` varchar(255) NOT NULL, 
    `name` varchar(255) NOT NULL, 
    `db_name` varchar(255) DEFAULT NULL, 
    PRIMARY KEY (`id`), 
    UNIQUE KEY `domain` (`domain`) 
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1; 

SELECT db_name FROM master.company WHERE db_name IN (SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA); 

不過,我可以得到它的工作時,我反向參考,像這樣的表:

SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME in (SELECT db_name FROM master.company);  

任何想法?

+0

無論你'select'語句應產生正確的結果。從你的成功查詢中出現一個'db_name'(第二個)並嘗試執行第一個,如下所示:'select ... where db_name in('')'。第二次嘗試是將schema_name和db_name強制轉換爲varchar(255)並查看。 – zedfoxus

回答

1

請參閱10.1.7.9 Collation and INFORMATION_SCHEMA Searches

嘗試:

SELECT `c`.`db_name` 
FROM `company` `c` 
    INNER JOIN `information_schema`.`SCHEMATA` `iss` 
    ON `c`.`db_name` = `iss`.`SCHEMA_NAME`; 

更新1

這真的看起來更像是與A項錯誤。

SQL Fiddle demo

請嘗試以下13.5 SQL Syntax for Prepared Statements

SET @`qry` := CONCAT(' 
SELECT 
    `id`, 
    `domain`, 
    `name`, 
    `db_name` 
FROM `company` 
WHERE `db_name` IN (', 
     (SELECT GROUP_CONCAT(CONCAT('\'', `SCHEMA_NAME`, '\'')) 
     FROM `information_schema`.`SCHEMATA`), 
')'); 
PREPARE `stmt` FROM @`qry`; 
EXECUTE `stmt`; 
DEALLOCATE PREPARE `stmt`; 

SQL Fiddle demo

記住要正確設置變量:group_concat_max_len

更新2

在早期版本中不會發生到MySQL 5.6的問題:

SQL Fiddle demo MySQL 5.6 SQL Fiddle demo MySQL 5.5

錯誤報告:Bug #77191 Subquery on information_schema including an IN clause, does not return results

UPDATE 3

解決方法:

SET @@session.optimizer_switch := 'semijoin=off'; 

SQL Fiddle demo MySQL 5.6

+0

更新3是爲我所需要的工作。我能夠設置optimizer_switch並按預期運行我的查詢。謝謝! –

相關問題