Mysql进入带NULL的OUTFILE嵌套联合,导致整数格式问题
我对SELECT INTO OUFILE有奇怪的行为,我没有找到答案 要继续,我有这样一张表:Mysql进入带NULL的OUTFILE嵌套联合,导致整数格式问题,mysql,union,redhat,myisam,into-outfile,Mysql,Union,Redhat,Myisam,Into Outfile,我对SELECT INTO OUFILE有奇怪的行为,我没有找到答案 要继续,我有这样一张表: CREATE TABLE `mytable` ( `id` 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`), ) ENGI
CREATE TABLE `mytable` (
`id` 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`),
) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
SELECT * INTO OUTFILE '/tmp/output.dat'
FIELDS TERMINATED BY '|'
OPTIONALLY ENCLOSED BY '\"'
ESCAPED BY ''
LINES TERMINATED BY '\n'
FROM mytable;
"12345678"|"20.00\0\0\0\0\0\0\0"|"1426513906\0"|"0\0\0\0"
"95863214"|"20.00\0\0\0\0\0\0\0"|"1426514075\0"|"1\0\0\0"
当我执行这样的查询时:
CREATE TABLE `mytable` (
`id` 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`),
) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
SELECT * INTO OUTFILE '/tmp/output.dat'
FIELDS TERMINATED BY '|'
OPTIONALLY ENCLOSED BY '\"'
ESCAPED BY ''
LINES TERMINATED BY '\n'
FROM mytable;
"12345678"|"20.00\0\0\0\0\0\0\0"|"1426513906\0"|"0\0\0\0"
"95863214"|"20.00\0\0\0\0\0\0\0"|"1426514075\0"|"1\0\0\0"
我在output.dat中获得如下结果:
"12345678"|"20.00^@^@^@^@^@^@^@"|"1426513906^@"|"0^@^@^@"
"95863214"|"20.00^@^@^@^@^@^@^@"|"1426514075^@"|"1^@^@^@"
无需通过以下方式转义:
我有这样一个结果:
CREATE TABLE `mytable` (
`id` 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`),
) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
SELECT * INTO OUTFILE '/tmp/output.dat'
FIELDS TERMINATED BY '|'
OPTIONALLY ENCLOSED BY '\"'
ESCAPED BY ''
LINES TERMINATED BY '\n'
FROM mytable;
"12345678"|"20.00\0\0\0\0\0\0\0"|"1426513906\0"|"0\0\0\0"
"95863214"|"20.00\0\0\0\0\0\0\0"|"1426514075\0"|"1\0\0\0"
Mysql环境:
"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"
看起来mysql试图用这个特殊字符填充,以便在mytble的结构中设置大小。用TRIM,我没有这个字符。但我想知道,这种行为只适用于整数和小数是正常的还是错误的?我还想知道是否有其他解决方案可以避免在每个字段中使用TRIM?因为我有很多比这个更复杂的查询
感谢您的帮助和花时间阅读我的帖子
问候
编辑:我认为问题可能只来自输入文件和类型字段。我没想到在这个例子中提到嵌套的联合。因此,我更改了标题,并回答了我的问题。上次编辑:要继续,找到的最佳解决方案是使用反斜杠强制退出,并且不要将其留空:
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;
注释来自:
如果按字符转义的字段为空,则不会转义任何字符
并且NULL被输出为NULL,而不是\N。这样做可能不是一个好主意
指定空转义字符,尤其是在
您的数据包含刚刚给出的列表中的任何字符
还要注意,如果指定一个空的转义值,则
可能无意中生成无法正确读取的输出
通过加载数据填充
以前的解决方案及说明:
我找到了问题的答案。
它来自具有空值的嵌套联合。我将举例说明这比长篇大论要好
这里是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或删除最后一个联合:
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
这只是一个简单的例子,不需要解释。在我的例子中,使用嵌套并集是因为在不同的条件下有不同的值
因此,在使用导出到输出文件的情况下,请小心使用空值的嵌套并集。在我的例子中,解决方案是在一个查询中融合嵌套的联合,而不使用联合
请注意,我没有在Windows 7上的Mysql 5.6.23 Mysql社区服务器上重现此案例。这不是原因。但你指出了我写这篇文章时犯的一个错误。我复制/粘贴了错误的查询。现在,它是正确的。谢谢你的评论。好的,仅供参考,我无法在5.6.20中重现这种行为。我不记得以前的版本有过这种行为。你如何看待结果?也许这不是MySQL的问题,而是你的编辑器/shell。我使用的是linux编辑器vi。它不是编辑器。当我尝试加载此类数据时,会出现类似“第1行'field1'列的数据被截断”这样的警告。编辑:我刚刚注意到,我没有主键的这种行为!奇怪!?