MySQL SELECT语法(一)SELECT...INTO语法

  源自MySQL 5.7 官方手册 SELECT...INTO Syntax

一、SELECT...INTO介绍

  SELECT...INTO用来将查询结果存储在变量或者写入文件中。

SELECT
...
...
[INTO OUTFILE 'file_name'
        [CHARACTER SET charset_name]
        export_options
      | INTO DUMPFILE 'file_name'
      | INTO var_name [, var_name]]

  通常有以下三种用法:

  • SELECT...INTO var_list,将查询结果存储在变量中;
  • SELECT...INTO OUTFILE 将查询结果写入一个文件,还可以指定列和行终止符以生成特定的输出格式。
  • SELECT...INTO DUMPFILE 将单行数据写入文件,没有任何格式。

  在SELECT的语法展示中,INTO子句在整个语句的尾部。但是让INTO子句紧跟在select_expr列表后。

  一个INTO子句不应该在内嵌的SELECT中使用,因为这样一个SELECT必须将它的查询结果返回给外部上下文。

  1.1 结果写入变量

  NTO子句可以命名一个或多个变量的列表,这些变量可以是用户自定义的变量,存储过程或函数的参数,或存储的程序的局部变量。而对于预编译的SELECT...INTO OUTFILE,只允许使用用户自定义变量,see Section 13.6.4.2, “Local Variable Scope and Resolution”。

  select后选定的值将分配给into后的变量,变量的数量必须与列数相匹配。如果查询未返回任何行,则会出现错误代码为1329的警告(No Data),并且变量的值保持不变。如果查询返回多个行,报错error 1172:Rseult consisted of more than one row,当然可以使用LIMIT 1来解决这个问题。

  用户自定义的变量对大小写不敏感,See Section 9.4, “User-Defined Variables”。

  1.2 SELECT ... INTO OUTFILE

SELECT ... INTO OUTFILE 'file_name'

  文件会在服务器主机上创建,所以用户必须拥有FILE权限才能使用该语法。

  同时,file_name不能是一个已经存在的文件,它会防止诸如/etc/passwd和数据库表等文件被损毁。character_set_filesystem系统变量控制文件名的解释。

  SELECT ... INTO OUTFILE语句主要用于让您非常快速地将表转储到服务器计算机上的text文件中。如果要在服务器主机之外的其他主机上创建结果文件,通常无法使用SELECT ... INTO OUTFILE,因为无法写出该文件相对于那个服务器主机的文件系统的路径。(there is no way to write a path to the file relative to the server host's file system.)

  但是,如果远程计算机上安装了MySQL客户端软件,则可以使用客户端命令在客户端主机上生成该文件,如:

mysql -e “SELECT ...”> file_name

  如果可以使用服务器文件系统上的网络映射路径访问远程主机上文件的位置,也可以在服务器主机以外的其他主机上创建生成的文件。在这种情况下,目标主机上不需要存在mysql(或其他一些MySQL客户端程序)

  SELECT ... INTO OUTFILE是LOAD DATA的补充。将列值转换为CHARACTER SET子句中指定的字符集。如果不存在此子句,则使用binary字符集转储值。实际上,没有字符集转换。如果结果集包含多个字符集中的列,则输出数据文件也将如此,您可能无法正确重新加载文件。

  该语句的export_options部分的语法,与LOAD DATA语句使用相同FIELDS和LINES子句。See 有关FIELDS和LINES子句的信息,请参见Section 13.2.6, “LOAD DATA Syntax”,包括其默认值和允许值。

三。关于输出格式

  FIELDS ESCAPED BY控制如何编写特殊字符。如果FIELDS ESCAPED BY字符不为空,则会在必要时使用它——将它作为后面将要输出的字符之前的前缀,以避免歧义:

  • FIELDS ESCAPED BY 字符;
  • FIELDS [OPTIONALLY] ENCLOSED BY 字符;
  • FIELDS TERMINATED BY和LINES TERMINATED BY值的第一个字符
  • ASCII NUL(零值字节;在转义字符后实际写入的是ASCII 0,而不是零值的字节)

   FIELDS TERMINATED BY, ENCLOSED BY, ESCAPED BY, or LINES TERMINATED BY 字符必须进行转义操作,以便能可靠地读取文件。而为了更方便地用页面查看,ASCII NUL 也会被转义。

  生成的文件不必符合SQL语法,因此不需要转义任何其他内容。

  如果FIELDS ESCAPED BY字符为空,则不转义任何字符,并将NULL输出为NULL,而不是\N。

  指定一个空的转义字符并不是一个好主意,尤其是当数据中的字段值包含刚刚给出的列表中的任何字符。

  下面是一个以许多程序使用的逗号分隔值(CSV)格式生成文件的示例:

SELECT a,b,a+b INTO OUTFILE '/tmp/result.txt'
  FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
  LINES TERMINATED BY '\n'
  FROM test_table;

  如果使用INTO DUMPFILE而不是INTO OUTFILE,MySQL只会在文件中写入一行,不会有任何列或行终止,也不会执行任何转义处理。如果要将BLOB值存储在文件中,这非常有用。

NOTES:

  由INTO OUTFILE或INTO DUMPFILE创建的任何文件都可由服务器主机上的所有用户写入。原因是MySQL服务器无法创建一个这样的文件:该文件的拥有者不是它所运行账户下的用户。(出于这个原因和其他原因,你永远不应该以root身份运行mysqld)因此,文件必须是world-writable的,以便您可以操作其内容。如果secure_file_priv系统变量设置为非空目录名,则要写入的文件必须位于该目录中。

  最后,在作为事件调度程序执行的事件的一部分发生的SELECT ... INTO语句的上下文中,诊断消息(不仅是错误,还包括警告)被写入错误日志,并且在Windows上写入应用程序事件日志。see Section 23.4.5, “Event Scheduler Status”.

四、自己执行SELECT...INTO碰到的问题

  我把上面的SELECT...INTO语句修改了一下,执行自己的版本导出数据时遇到了错误。

  于是查看当前用户的权限:

  这块不太懂,搜索说需要"FILE"权限,我以为自己没有“FILE”权限(实际已经有了),于是想赋给当前用户这个权限:

  没什么影响,只是提一下这个过程。

  有了“FILE”权限,还是报错不能执行:

ERROR 1290 (HY000): The MySQL server is running with the --secure-file-priv option so it cannot execute this statement

  涉及到secure_file_priv这个系统变量:

  根据前一章的提示,我只能把输出文件放到这个目录下。

  还有就是这个系统变量是只读的,无法直接通过SQL修改。具体的修改方法可以搜索。

  继续。

  现在有新的问题:

  查询结果显示,系统变量secure_file_priv=C:\ProgramData\MySQL\MySQL Server 5.7\Uploads\ 

  Windows的文件管理器的地址栏现实的也是:C:\ProgramData\MySQL\MySQL Server 5.7\Uploads

  如下语句仍然不能执行:

SELECT * INTO OUTFILE 'C:\ProgramData\MySQL\MySQL Server 5.7\Uploads\sqltraining_stu.txt'
  FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
  LINES TERMINATED BY '\n'
  FROM student;

/*

ERROR 1290 (HY000): The MySQL server is running with the 
--secure-file-priv option so it cannot execute this statement

*/

  报错也没变,但现在只能是文件路径的格式问题了。修改路径分隔符,执行成功。

SELECT * INTO OUTFILE 'C:/ProgramData/MySQL/MySQL Server 5.7/Uploads/sqltraining_stu.txt'
  FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
  LINES TERMINATED BY '\n'
  FROM student;

/*

rows affected (0.00 sec)

*/

  

猜你喜欢

转载自www.cnblogs.com/bigbigbigo/p/10958743.html