简体   繁体   English

无需输入mysql命令行即可收集mysql查询结果

[英]Gather mysql query results without having to enter mysql command line

I have multiple tables that I want to add to a database, and I anticipate some of the queries failing so I want to gather the pertinent information like the following: 我有多个表要添加到数据库中,并且我预计某些查询会失败,因此我想收集以下相关信息:

mysql> drop table user;
Query OK, 0 rows affected (0.00 sec)

I haven't been able to figure out how to capture this information on the bash command line. 我还无法弄清楚如何在bash命令行上捕获此信息。 I've tried the following: 我尝试了以下方法:

mysql --force -ujay -p db < create.sql > log.txt 2> error.txt

... but only error log gets populated -- how can I acquire the "Query OK" messages external to mysql? ...但是仅填充错误日志-如何获取mysql外部的“ Query OK”消息?


I've edited the script so that I'm outputting to a file and then grepping for problems: 我已经编辑了脚本,以便输出到文件,然后grepping问题:

mysql -vv --force -ujay -p db < create.sql &>> log.txt
grep -i '^Query\|^Warning\|^ERROR' log.txt

The problem here is that the results: 这里的问题是结果:

ERROR 1050 (42S01) at line 28: Table 'db' already exists
Query OK, 0 rows affected
Query OK, 0 rows affected

are NOT in the order of which the queries get executed. 不是按照查询执行的顺序。 The first and third queries are successful, so the order should look as follows: 第一个和第三个查询成功,因此顺序应如下所示:

Query OK, 0 rows affected
ERROR 1050 (42S01) at line 28: Table 'db' already exists
Query OK, 0 rows affected

The order is EXTREMELY important in this situation. 在这种情况下,此命令极其重要。

This is how the log looks after being created: 这是创建日志后的样子:

--------------
ERROR 1050 (42S01) at line 28: Table 'db' already exists
--------------
CREATE TABLE `db` (
  `Host` char(60) COLLATE utf8_bin NOT NULL DEFAULT '',
  `Db` char(64) COLLATE utf8_bin NOT NULL DEFAULT '',
  `User` char(32) COLLATE utf8_bin NOT NULL DEFAULT '',
  `Select_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `Insert_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `Update_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `Delete_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `Create_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `Drop_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `Grant_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `References_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `Index_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `Alter_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `Create_tmp_table_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `Lock_tables_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `Create_view_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `Show_view_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `Create_routine_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `Alter_routine_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `Execute_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `Event_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `Trigger_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  PRIMARY KEY (`Host`,`Db`,`User`),
  KEY `User` (`User`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='Database privileges'
--------------
Query OK, 0 rows affected

--------------
CREATE TABLE `db` (
  `Host` char(60) COLLATE utf8_bin NOT NULL DEFAULT '',
  `Db` char(64) COLLATE utf8_bin NOT NULL DEFAULT '',
  `User` char(32) COLLATE utf8_bin NOT NULL DEFAULT '',
  `Select_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `Insert_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `Update_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `Delete_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `Create_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `Drop_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `Grant_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `References_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `Index_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `Alter_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `Create_tmp_table_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `Lock_tables_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `Create_view_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `Show_view_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `Create_routine_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `Alter_routine_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `Execute_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `Event_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `Trigger_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  PRIMARY KEY (`Host`,`Db`,`User`),
  KEY `User` (`User`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='Database privileges'
--------------

--------------
CREATE TABLE `db1` (
  `Host` char(60) COLLATE utf8_bin NOT NULL DEFAULT '',
  `Db` char(64) COLLATE utf8_bin NOT NULL DEFAULT '',
  `User` char(32) COLLATE utf8_bin NOT NULL DEFAULT '',
  `Select_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `Insert_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `Update_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `Delete_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `Create_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `Drop_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `Grant_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `References_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `Index_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `Alter_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `Create_tmp_table_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `Lock_tables_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `Create_view_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `Show_view_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `Create_routine_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `Alter_routine_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `Execute_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `Event_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `Trigger_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  PRIMARY KEY (`Host`,`Db`,`User`),
  KEY `User` (`User`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='Database privileges'
--------------

Query OK, 0 rows affected

Bye

As you can see the messages do not appear in the correct order (and I'm not sure why the create table statements appear at all -- something to do with the -vvv flag I assume). 如您所见,消息没有以正确的顺序出现(并且我不确定为什么create table语句根本出现-与我假设的-vvv标志有关)。

The problem here is that in linux stdout is buffered while errout is unbuffered. 这里的问题是在linux中stdout被缓冲,而errout没有缓冲。 That basically means that stdout will wait until it has eg 8kb of data before it writes to the file, while errout will write at once, thus resulting in a different order. 基本上,这意味着stdout将等到它具有例如8kb的数据后再写入文件,而errout将立即写入,从而导致顺序不同。 So your logfile would usually look something like stderr messages that happened during first 8kb of stdoutdata - 8kb of stdoutdata - stderr messages during next 8kb of stdoutdata - next 8kb of stdoutdata - ... . 所以,你的日志文件通常会看起来像stderr messages that happened during first 8kb of stdoutdata - 8kb of stdoutdata - stderr messages during next 8kb of stdoutdata - next 8kb of stdoutdata - ...

You can force mysql to flush the (stdout) buffer after each query by using the option -n or --unbuffered , so eg 您可以使用选项-n--unbuffered强制mysql在每次查询后刷新(stdout)缓冲区,例如

mysql -vv -n --force -ujay -p db < create.sql &>> log.txt
grep -i '^Query\|^Warning\|^ERROR' log.txt

should give you the correct order. 应该给您正确的顺序。

Btw., --show-warnings is false by default, so if you want to get warnings too as your grep implies, you might want to add --show-warnings . 顺便说一句,-- --show-warnings默认情况下为false,因此,如果您也想按grep要求获得警告,则可能需要添加--show-warnings

An alternative would be to just split up your create statements in seperate files (or not put them in one file to begin with) and call mysql for each of them, which would give you the opportunity to react in your program directly to a missing table and it would guarantee the creation order and its logic (eg if you create the table db1 , db , db and the first one fails, and the second one has a reference to db1 and therefore fails too, the third table db will be created. Correcting db1 afterwards and repeating it will now not be the same as if it had been correct the first time, as now the second table will fail, because the third already exists, instead of the third table failing because the second table already exists.) 一种替代方法是将您的create语句拆分为单独的文件(或不将它们放入一个文件中),然后为每个文件调用mysql,这将使您有机会在程序中直接对丢失的表做出反应并且可以保证创建顺序及其逻辑(例如,如果您创建表db1dbdb ,而第一个表失败,而第二个表对db1的引用也因此失败,那么将创建第三个表db 。之后更正db1并重复执行该操作将与第一次校正现在不同,因为现在第二个表将失败,因为第三个表已经存在,而不是第三个表因第二个表已经存在而失败。)

现在,一个简单的解决方案是将grep更改为sed-假设grep是问题所在。

sed -n '/^Query/p; /^Warning/p; /^Error/p' log.txt

This merges the two outputs together. 这会将两个输出合并在一起。 Will that do what you need? 那会满足您的需求吗?

>log.txt  2>&1

But I would argue that shell scripting is not the way to execute SQL. 但是我会说Shell脚本不是执行SQL的方法。 Instead, use some language that has more facilities, such as Perl. 相反,请使用具有更多功能的某种语言,例如Perl。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM