最后编辑: 要恢复,找到的最佳解决方案是用反斜杠强制转义,而不是将其留空:
SELECT * INTO OUTFILE '/tmp/output1.dat'
FIELDS TERMINATED BY '|'
ENCLOSED BY '\"'
ESCAPED BY '\\'
LINES TERMINATED BY '\n'
FROM
((SELECT
id_test,
field2,
field3
FROM mytable1)
UNION
(SELECT
*
FROM
((SELECT
id_test,
field2,
NULL AS field3
FROM mytable2)
UNION
(SELECT
id_test,
NULL AS field2,
NULL AS field3
FROM mytable3)
) test)
) tmptable;
mysql文档中的注释:
如果 FIELDS ESCAPED BY 字符为空,则不转义任何字符,并且 NULL 输出为 NULL,而不是 \N。指定空转义字符可能不是一个好主意,尤其是当数据中的字段值包含刚刚给出的列表中的任何字符时。
……
另请注意,如果您指定一个空的 ESCAPED BY 值,则可能会无意中生成 LOAD DATA INFILE 无法正确读取的输出。
以前的解决方案有解释:
我找到了我的问题的答案。它来自具有 NULL 值的嵌套联合。我会用例子来解释它比长篇大论更好。
这里是mysql上下文:
DROP TABLE IF EXISTS `mytable1`;
CREATE TABLE `mytable1` (
`id_test` INT(11) NOT NULL AUTO_INCREMENT,
`field1` DECIMAL(10,2) DEFAULT NULL,
`field2` INT(11) DEFAULT NULL,
`field3` TINYINT(4) DEFAULT NULL,
PRIMARY KEY (`id_test`)
) ENGINE=MYISAM AUTO_INCREMENT=95863215 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
/*Data for the table `mytable` */
INSERT INTO `mytable1`(`id_test`,`field1`,`field2`,`field3`) VALUES (12345678,20.00,1426513906,0),(95863214,20.00,1426514075,1);
/*Table structure for table `mytable2` */
DROP TABLE IF EXISTS `mytable2`;
CREATE TABLE `mytable2` (
`id_test` INT(11) NOT NULL AUTO_INCREMENT,
`field1` DECIMAL(10,2) DEFAULT NULL,
`field2` INT(11) DEFAULT NULL,
PRIMARY KEY (`id_test`)
) ENGINE=MYISAM AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
/*Data for the table `mytable2` */
INSERT INTO `mytable2`(`id_test`,`field1`,`field2`) VALUES (1,25.00,12345),(2,11.00,52146);
/*Table structure for table `mytable3` */
DROP TABLE IF EXISTS `mytable3`;
CREATE TABLE `mytable3` (
`id_test` INT(11) NOT NULL AUTO_INCREMENT,
`field1` DECIMAL(10,2) DEFAULT NULL,
`field3` TINYINT(4) DEFAULT NULL,
PRIMARY KEY (`id_test`)
) ENGINE=MYISAM AUTO_INCREMENT=5 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
/*Data for the table `mytable3` */
INSERT INTO `mytable3`(`id_test`,`field1`,`field3`) VALUES (2,12.00,2),(4,23.00,31);
并与环境:
"protocol_version";"10"
"version";"5.0.67-community-log"
"version_comment";"MySQL Community Edition (GPL)"
"version_compile_machine";"x86_64"
"version_compile_os";"redhat-linux-gnu"
或者用这个:
"protocol_version";"10"
"version";"5.0.95-log"
"version_bdb";"Sleepycat Software: Berkeley DB 4.1.24: (December 16, 2011)"
"version_comment";"Source distribution"
"version_compile_machine";"x86_64"
"version_compile_os";"redhat-linux-gnu"
我们用这种查询重现这个案例:
SELECT * INTO OUTFILE '/tmp/output1.dat'
FIELDS TERMINATED BY '|'
ENCLOSED BY '\"'
ESCAPED BY ''
LINES TERMINATED BY '\n'
FROM
((SELECT
id_test,
field2,
field3
FROM mytable1)
UNION
(SELECT
*
FROM
((SELECT
id_test,
field2,
NULL AS field3
FROM mytable2)
UNION
(SELECT
id_test,
NULL AS field2,
NULL AS field3
FROM mytable3)
) test)
) tmptable;
我们得到这个结果:
"12345678"|"1426513906"|"0^@^@^@"
"95863214"|"1426514075"|"1^@^@^@"
"1"|"12345"|NULL
"2"|"52146"|NULL
"2"|NULL|NULL
"4"|NULL|NULL
例如,当我们用 1 替换最后一个 NULL 或删除最后一个 union 来执行相同的查询时:
SELECT * INTO OUTFILE '/tmp/output1.dat'
FIELDS TERMINATED BY '|'
ENCLOSED BY '\"'
ESCAPED BY ''
LINES TERMINATED BY '\n'
FROM
((SELECT
id_test,
field2,
field3
FROM mytable1)
UNION
(SELECT
*
FROM
((SELECT
id_test,
field2,
NULL AS field3
FROM mytable2)
UNION
(SELECT
id_test,
NULL AS field2,
1 AS field3
FROM mytable3)
) test)
) tmptable;
我们得到了预期的正确结果:
"12345678"|"1426513906"|"0"
"95863214"|"1426514075"|"1"
"1"|"12345"|NULL
"2"|"52146"|NULL
"2"|NULL|1
"4"|NULL|1
这只是一个简单的例子,没有在哪里解释。在我的例子中,使用嵌套联合是因为我们在不同的条件下有不同的值。
因此,在使用INTO OUTFILE导出的情况下,请小心使用具有NULL值的嵌套UNION。就我而言,解决方案是在一个没有UNION的查询中使用熔断器嵌套联合。
请注意,我没有在 Windows 7 上使用 Mysql 5.6.23 MySQL Community Server 重现此案例。