我正在尝试使用awk将.tsv文件的一些数据插入mysql数据库。当我运行它时,我只是在命令行中获得了mysql规则。有任何想法吗?
这是我正在使用的命令:
awk '{print "INSERT INTO scores(id, score) VALUES('\''"$1"'\'', "$2");"}' "data.tsv" | mysql -u "user" -p "passw" db
我没有收到任何错误消息,但是我检查数据库并且没有插入行。
答案 0 :(得分:1)
您可以尝试删除-p "passw"
之间的空格,如下所示:
| mysql -u "user" -p"passw" db
答案 1 :(得分:1)
另一个答案已经暗示-p
标志在mysql客户端中具有特殊的,违反直觉的行为。如果后面有空格,它将使mysql客户端提示您输入密码。后面的参数不作为密码,而作为下一个与-p
不相关的参数。
以下两个命令是等效的:
mysql -u <user> -p <databasename>
mysql -p -u <user> <databasename>
如果要包含密码,则-p
后必须没有空格:
mysql -u <user> -p<password> <databasename>
为了使脚本更加清晰,我喜欢使用长选项名称:
mysql --user=<user> --password=<password> <databasename>
但是无论如何,您都不应该在命令行上使用密码,因为那样的话,任何可以运行ps
的人都可以看到您的密码。而是将用户名和密码放入options file中,让客户端读取它。
mysql --defaults-file my.cnf <databasename>
您的awk代码将输出一系列SQL注入漏洞。我的意思是,您相信.tsv文件中的所有内容都可以安全插入,不会包含诸如撇号之类的任何字符,这些字符会对SQL语法产生意外的影响。例如,如果$1
是“奥黑尔”,会发生什么?
Awk没有任何功能可进行字符串转义来保护您免受此攻击,也没有任何功能可进行参数化查询,这是一种运行带有动态值的安全SQL语句的更好方法。
我已经将awk用于其他任务很多年了,但是我不会将其用于此任务。例如,在Ruby中:
require 'mysql2'
require 'csv'
client = Mysql2::Client.new(:host => "localhost", :database => "test", :username => "...")
sql = client.prepare("INSERT INTO scores (id, score) VALUES (?, ?)")
CSV.open('data.tsv', col_sep: "\t", liberal_parsing: true) do |csv|
csv.each do |row|
sql.execute(*row)
end
end
另一种加载TSV文件的替代方法是使用mysqlimport --local,它具有更好的性能。但是有一些configuration values you need to set可以使它在默认的MySQL实例上运行,并且文件名必须与表具有相同的名称(.tsv文件扩展名除外)。
示例:我将包含四行文本的.tsv文件加载到表test.scores
中:
mysqlimport --local test scores.tsv
test.scores: Records: 4 Deleted: 0 Skipped: 0 Warnings: 0