2015-05-29 81 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并按预期运行我的查询。谢谢! –

相关问题