将MySQL查询结果存储到shell变量中

53

我需要一个变量来存储从数据库检索到的结果。目前这就是我的基本尝试,但并没有成功。

myvariable=$(mysql database -u $user -p $password | SELECT A, B, C FROM table_a)

正如你所看到的,我对bash命令的理解并不是很好。


你是将 $user 和 $password 的值分别存储在不同的行中吗? - Murtaza Haji
11个回答

92
更直接的方法是:
myvar=$(mysql mydatabase -u $user -p$password -se "SELECT a, b, c FROM table_a")

12
我正在搜索"S参数",但您需要将其提供两次以抑制打印列名。 - Dominic
1
这应该是最好的答案,它不返回列名! - Ivan Borshchov
2
我认为必须删除“-p”和密码之间的空格。 - frb
正如frb所说,您需要在-p和密码之间删除空格。 - fred
这对我有效:myvar=$(mysql mydatabase -h <host> -u $user -p$password -se "SELECT a, b, c FROM table_a;") => 我添加了两个元素:1)主机地址和2)分号到SELECT查询中。 - Andrii

57

我对MySQL命令行界面不是很了解,但假设你只需要关于bash的帮助,应该尝试交换命令的顺序,如下所示:

myvariable=$(echo "SELECT A, B, C FROM table_a" | mysql database -u $user -p$password)

你可以使用echo将字符串输出到MySQL中。或者,你也可以更高级地使用一些新的bash特性(比如here string)。

你可以使用echo将字符串输出到MySQL中。或者,你也可以更高级地使用一些新的bash特性(比如here string)。

myvariable=$(mysql database -u $user -p$password<<<"SELECT A, B, C FROM table_a")

如果使用足够新的bash版本,可以避免使用echo并得到相同的结果。

请注意,-p$password 不是打字错误,而是MySQL要求通过命令行输入密码的方式(选项和值之间没有空格)。

请注意,myvariable将包含MySQL在标准输出上输出的所有内容(通常除了错误消息以外的所有内容),包括任何列标题、ASCII艺术框架等内容,这可能不是您想要的。

编辑:
如已指出,MySQL似乎有一个-e参数,我一定会选择那个。


1
谢谢,mysql 命令也不喜欢 -p... 我需要使用 --password=$password。 - imnotneo
1
你也可以在你的主目录下添加一个配置文件(称为.my.cnf),它将自动插入你的选项。这将节省你脚本中的一些混乱。 - Isaac
1
在编程中,对于.my.cnf文件的+1操作尤为重要,特别是为了避免在脚本中暴露密码。使用-N选项可以很好地修剪字段名称。 - ErichBSchulz
在得到最多投票的回答中,-s选项会删除列名并仅提供值。 - Glasnhost
1
趣闻:关于-p$password选项。POSIX标准允许,尽管不鼓励,可选的选项属性。与强制选项属性不同,后者在选项之后用<blank>字符分隔显示(例如-u $user),可选的选项参数包含在与选项相同的参数字符串中(即没有空格)。如果您觉得这种语法令人困惑(我也是),您可以使用GNU长参数语法:--password=$password。无论如何,我还建议使用my.cnf文件,因为这已经被建议过了。 - David

19

你需要反转管道并打印查询结果,像这样:

myvariable=$(echo "SELECT A, B, C FROM table_a" | mysql db -u $user -p $password)

另一种选择是仅使用mysql客户端,像这样:

myvariable=$(mysql db -u $user -p $password -se "SELECT A, B, C FROM table_a")

需要使用-s选项来避免生成ASCII图案。

BASH并不是最适合处理这种场景的语言,特别是在处理字符串、拆分SQL结果等方面。你需要花费很多精力去做那些在Perl、Python或PHP中非常简单的事情。

例如,如何将A、B和C分别存储到它们自己的变量中?这肯定是可行的,但如果你不了解管道和echo(非常基础的shell内容),那么这对你来说将不是一项容易的任务,所以如果可能的话,我建议使用更适合的语言。


感谢使用 -s 来避免 ASCII。 - Matt Komarnicki

18

要逐行读取数据并存入 Bash 数组中,可以使用以下方法:

while read -a row
do
    echo "..${row[0]}..${row[1]}..${row[2]}.."
done < <(echo "SELECT A, B, C FROM table_a" | mysql database -u $user -p $password)

或者将它们分配给单独的变量:

while read a b c
do
    echo "..${a}..${b}..${c}.."
done < <(echo "SELECT A, B, C FROM table_a" | mysql database -u $user -p $password)

syntax error near unexpected token <' cut.sh: line 26: done < < - thevoipman
@thevoipman:很可能你的脚本没有使用Bash。你的shebang写了什么?另外,由于我看不到你的脚本,也看不到错误可能在哪里。 - Dennis Williamson
@thevoipman,进程替换似乎是您的问题(是的,我知道,一年前的事情,只是如果有人来找),但在您使用的任何shell中,可能可以使用管道来进行反向操作,即echo ... | mysql ... | while read -a row; do ...; done。请记住,while体位于子shell中,不会影响其周围的shell。 - falstro

10

如果你想在bash中使用单个值,请使用:

  companyid=$(mysql --user=$Username --password=$Password --database=$Database -s --execute="select CompanyID from mytable limit 1;"|cut -f1)

  echo "$companyid"

3
MySQL接受--skip-column-names (-N),而不是| cut -f1 - jon

5

其他方法:

您的脚本:

#!/bin/sh

# Set these variables
MyUSER="root"   # DB_USERNAME
MyPASS="yourPass"   # DB_PASSWORD
MyHOST="yourHost"    # DB_HOSTNAME
DB_NAME="dbName"
CONTAINER="containerName" #if use docker

# Get data
data=$($MyHOST -u $MyUSER -p$MyPASS $DB_NAME -h $CONTAINER -e "SELECT data1,data2 from table_name LIMIT 1;"  -B --skip-column-names)

# Set data
data1=$(echo $data | awk '{print $1}')
data2=$(echo $data | awk '{print $2}')

# Print data
echo $data1 $data2

4
“-N”可用于“--skip-column-names”。 - Steven
这个答案非常有用! - Rohit Parte

3
myvariable=$(mysql database -u $user -p$password | SELECT A, B, C FROM table_a)

-p后面没有空格。这很琐碎,但如果没有空格就不起作用。

如果密码包含特殊字符,则可能需要添加引号:-p“YOURCOMPLEXPASSWORD” - webcoder.co.uk

2

如果您有特定的数据库名称和要执行查询的主机,请使用以下查询:

outputofquery=$(mysql -u"$dbusername" -p"$dbpassword" -h"$dbhostname" -e "SELECT A, B, C FROM table_a;" $dbname)

因此,要在Linux上运行MySQL查询,您需要安装MySQL客户端。


0

我在这里说两句:

myvariable=$(mysql database -u $user -p$password -sse "SELECT A, B, C FROM table_a" 2>&1 \
   | grep -v "Using a password")

移除列名和烦人的(但必要的)密码警告。感谢@Dominic Bartl和John提供此答案


0

另一个例子是当表名或数据库包含不支持的字符,例如空格或“-”时

db='data-base'

db_d=''
db_d+='`'
db_d+=$db
db_d+='`'

myvariable=`mysql --user=$user --password=$password -e "SELECT A, B, C FROM $db_d.table_a;"`

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接