暂无图片
暂无图片
1
暂无图片
暂无图片
暂无图片

如何将 MySQL 查询输出保存到文件?

原创 Shubing Wu 2022-11-15
5228

您是否需要将MySQL查询的结果保存到CSV或文本文件中?

这在MySQL中很容易做到。您可以使用IDE或命令行,使用内置的MySQL命令来完成此操作。

让我们来看看。


基本查询

让我们为此使用一个SELECT语句的简单示例。

SELECT id, first_name, last_name
FROM customer;

这是结果:

idfirst_namelast_name
1JohnSmith
2MaryMcAdams
3StevePitt
4MarkCousins
5ShaunJones
7AmyMcDonald
8BradSwan
10WendyJohnson

我们可以在命令行或IDE(如MySQL Workbench)的输出中看到这些结果。

如何将它们保存到文本文件中?

我们可以复制粘贴它们,但那样很慢,而且需要手动操作。


将MySQL结果保存到一个文件

在SELECT语句中有一个内置的MySQL输出到文件特性。

我们只需在SELECT语句的末尾添加INTO OUTFILE字样,后面跟着一个文件名。

例如:

SELECT id, first_name, last_name
FROM customer
INTO OUTFILE '/temp/myoutput.txt';

这将在名为temp的文件夹中创建一个名为myoutput.txt的新文件,其中包含该查询的结果。

如果您得到这个错误(像我一样)会发生什么?

Error Code: 1290. The MySQL server is running with the –secure-file-priv option so it cannot execute this statement

我将在本指南后面详细解释如何解决这个问题。

现在,假设你可以运行这个语句来生成文件,它看起来像这样:

mysql output file 1

文件中的文本是:

1 John Smith
2 Mary McAdams
3 Steve Pitt
4 Mark Cousins
5 Shaun Jones
7 Amy McDonald
8 Brad Swan
10 Wendy Johnson

如您所见,字段由选项卡分隔。这是默认的行为,但可以更改。


更改参数以设置逗号分隔值

您可以更改这个INTO OUTFILE关键字的参数来更改文件的写入方式。

还有几个额外的参数。下面是一些最常见的:

FIELDS TERMINATED BY:表示用于结束字段的字符。

ENCLOSED BY:表示将用于围合每个字段的字符。

LINES TERMINATED BY:表示用于结束一行和开始新一行的字符。

例如,要选择CSV文件中的数据并将每个字段用双引号括起来:

SELECT id, first_name, last_name
FROM customer
INTO OUTFILE '/temp/myoutput.txt'
FIELDS TERMINATED BY ','
ENCLOSED BY '"'
LINES TERMINATED BY '\n';

如果我们运行这条语句,我们可以检查文件,它看起来像这样:

mysql output file

文件中的文本是:

"1","John","Smith"
"2","Mary","McAdams"
"3","Steve","Pitt"
"4","Mark","Cousins"
"5","Shaun","Jones"
"7","Amy","McDonald"
"8","Brad","Swan"
"10","Wendy","Johnson"

这就是如何在MySQL中生成CSV或文本文件。您只需将INTO OUTFILE关键字添加到SELECT查询的末尾并指定一些参数。


在输出文件中包含标题

您可能已经注意到,输出文件中没有列标题。

如何显示列标题?不幸的是,没有可以启用的简单选项。

一种常用的方法是使用UNION ALL来选择列标题和数据。

所以,你的查询是这样的:
SELECT 'id', 'first_name', 'last_name'
UNION ALL
SELECT id, first_name, last_name
FROM customer
INTO OUTFILE '/temp/myoutput.txt'
FIELDS TERMINATED BY ','
ENCLOSED BY '"'
LINES TERMINATED BY '\n';

这意味着你的列标题将显示在文件中:

"id","first_name","last_name"
"1","John","Smith"
"2","Mary","McAdams"
"3","Steve","Pitt"
"4","Mark","Cousins"
"5","Shaun","Jones"
"7","Amy","McDonald"
"8","Brad","Swan"
"10","Wendy","Johnson"

然而,这也存在一些问题:


数据类型

这仅在数据类型为字符时有效。如果您的数据中有任何其他类型(例如数字或日期),那么您的查询将出现问题。

这是因为列的数据类型是由UNION中的第一个查询确定的。所有列标题都是文本值,因此当UNION查询的第二部分运行时,它可能试图向字符列添加日期并导致错误。


排序会有问题吗

如果查询包含ORDER BY子句,则列标题将无法正确显示。

这是因为ORDER BY子句位于查询的末尾,并将在排序中包含列标题行。这可能意味着您的列标题将在结果中的一个不是顶部的位置结束。

您可以通过将主查询放在子查询中,然后在子查询上使用UNION来解决这个问题。

例如:

SELECT *
FROM 
(
  SELECT 'id', 'first_name', 'last_name'
  UNION ALL
  (
    SELECT id, first_name, last_name
    FROM customer
    ORDER BY first_name ASC
  )
) sub
INTO OUTFILE '/temp/myoutput.txt';

这应该确保列标题显示在顶部。


可能的性能问题

如果您尝试使用UNION或UNION ALL, MySQL数据库可能会尝试使用不同的执行计划来显示数据,即使您只添加了一行。

这可能意味着运行时要慢得多。所以,在你开始使用它作为永久解决方案之前,你应该进行测试。


如果文件已经存在怎么办?

那么,如果您尝试此命令,而该文件已经存在,会发生什么情况呢?

例如,假设存在myoutput.txt文件,运行以下命令:

SELECT id, first_name, last_name
FROM customer
INTO OUTFILE '/temp/myoutput.txt'
FIELDS TERMINATED BY ','
ENCLOSED BY '"'
LINES TERMINATED BY '\n';

你会收到这条消息:

Error Code: 1086. File ‘/temp/myoutput.txt’ already exists

这很明显。该文件已经存在。因此,您需要使用一个不存在的文件名。


Secure-File-Priv错误

你运行这个SELECT到OUTFILE和得到一个关于“secure-file-priv”的错误吗?

Error Code: 1290. The MySQL server is running with the –secure-file-priv option so it cannot execute this statement

这本质上意味着MySQL有一组可用于输入和输出的特定目录,而我们试图写入的文件不在该目录中。

为了解决这个问题,我们需要:

  1、找出具体的目录是什么

  2、将这个目录路径添加到OUTFILE参数中,这样我们的文件就会在那里生成。

为了找到目录的位置,我们可以运行这两个命令中的任何一个:

SELECT @@GLOBAL.secure_file_priv;
@@GLOBAL.secure_file_priv
/usr/files/
SHOW VARIABLES LIKE "secure_file_priv";
Variable_nameValue
secure_file_priv/usr/files/

本例中的输出显示值为' /usr/files/ '。

因此,您所需要做的就是将此路径添加到OUTFILE路径的开头。

你的SELECT语句看起来像这样:

SELECT id, first_name, last_name
FROM customer
INTO OUTFILE '/usr/files/temp/customer.txt'


Secure-File-Priv为NULL

如果出现上述错误,并查找secure_file_priv变量,您可能会发现它是NULL。这种情况最常发生在带有MAMP的MacOS上。

SHOW VARIABLES LIKE "secure_file_priv";
Variable_nameValue
secure_file_privNULL

为了解决这个问题,我们需要将这个变量添加到my.cnf文件中。

首先,通过打开MAMP并单击stop来停止MAMP服务器。

打开终端窗口。

terminal1

输入以下命令:

vi ~/.my.cnf

您的屏幕应该如下所示。

terminal2

按“Enter”执行命令。这将打开my.cnf文件的编辑器。

复制以下行到终端窗口:

[mysqld_safe]
[mysqld]
secure_file_priv="/Users/BB/"

(将字母BB替换为你的用户文件夹)

terminal3

按:键,光标会移动到最下方。

terminal4

在:之后输入wq,这将写入文件并退出。

terminal5

按回车键,返回正常的终端窗口。

现在,再次启动MAMP。

你可以通过运行前面的命令来测试变量的设置:

SHOW VARIABLES LIKE "secure_file_priv";
Variable_nameValue
secure_file_priv/Users/BB/

现在,更新SELECT INTO语句,将这里的值添加到OUTFILE的路径:

SELECT id, first_name, last_name
FROM customer
INTO OUTFILE '/Users/BB/customer.txt';

现在将生成该文件。


结论

以上就是如何从MySQL查询的结果中生成文本或CSV文件的方法。在SELECT查询的末尾添加一个INTO OUTFILE参数。如果错误消息有任何问题,它们通常与权限相关。


原文标题:How to Save MySQL Query Output to a File
原文作者:Ben Brumm
原文地址:https://www.databasestar.com/mysql-output-file/

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
2人已赞赏
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论