Perl脚本执行mysql命令?

时间:2011-08-03 16:07:36

标签: mysql perl

我是Perl的新手,并且正在尝试在RHEL框上编写脚本,该脚本将为我们在主机上创建的新网站自动配置vanilla数据库。我已经有连接语句工作,我能够连接并从脚本创建一个数据库(使用$ dbh-> do(qq(CREATE DATABASE $ dbcreate));这是最好的方法???),但是我有一些我无法弄清楚如何让它们发挥作用。

这些是我遇到问题的mysql命令。有什么建议?谢谢!

$dbh = DBI->connect("DBI:mysql:$db:$host", $user, $pass);
$dbh->do( qq(CREATE DATABASE $dbcreate) );
$dbh->do(qq(GRANT SELECT , INSERT , UPDATE , DELETE , CREATE , DROP , INDEX , ALTER , CREATE TEMPORARY TABLES , CREATE VIEW , SHOW VIEW , CREATE ROUTINE, ALTER ROUTINE, EXECUTE ON `$dbcreate` . * TO 'moodle'@'%'`) );
$dbh->do( qq(FLUSH PRIVILEGES) );
$dbh->do( qq($dbcreate < MySQL_pristine.sql) );
$dbh->do( qq(USE $dbcreate) );
$dbh->do( qq(UPDATE md1_label SET content = REPLACE( content, "pristine", "$dbcreate")) );
$dbh->do( qq(UPDATE md1_label SET contents = REPLACE( contents, "pristine", "$dbcreate")) );
$dbh->do( qq(UPDATE md1_label SET questiontext = REPLACE( questiontext, "pristine", "$dbcreate")) );

DBD::mysql::db do failed: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'GRANT SELECT , INSERT , UPDATE , DELETE , CREATE , DROP , INDEX ,�' at line 1 at create-auto-db.pl line 52.
DBD::mysql::db do failed: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'test3 < MySQL_pristine.sql' at line 1 at create-auto-db.pl line 54.
DBD::mysql::db do failed: Table 'test3.md1_label' doesn't exist at create-auto-db.pl line 56.
DBD::mysql::db do failed: Table 'test3.md1_label' doesn't exist at create-auto-db.pl line 57.
DBD::mysql::db do failed: Table 'test3.md1_label' doesn't exist at create-auto-db.pl line 58.

2 个答案:

答案 0 :(得分:0)

您遇到的主要问题是插入包含at符号的字符串。如果您有类似qq{Here is my email: test@hotmail.com}的内容 - 这会失败,因为它会尝试放置一个不存在的列表变量@hotmail。使用反斜杠来转义它(即qq{Here is my email: test\@hotmail.com}),或者如果您不需要插入任何变量,请使用非插值引用q{...}

话虽如此,你需要对这些陈述有点小心。您将变量值放入这些SQL语句中,这是SQL注入攻击的风险。我使用$dbh->quote($dbcreate)获取字符串版本,$dbh->quote_identifier($dbcreate)获取$dbcreate值的标识符版本,并将这些值嵌入。这样更安全,因为它会更安全避免有人在你身上做Bobby表并给你一个数据库名称,如:db'; DROP TABLE mysql.user; ';或类似的。 DBI提供字符串和标识符引用,因此您可以根据需要获得正确的引用类型。例如:

my $quoted_id_dbcreate = $dbh->quote_identifier($dbcreate);
$dbh->do( qq(USE $quoted_id_dbcreate) );

占位符通常更好,但其中一些管理语句可能不支持它们,因此可能需要使用适当的引用来注入值。

答案 1 :(得分:0)

有两件事让我感到高兴。

$dbh->do(qq(GRANT SELECT , INSERT , (snip), EXECUTE ON '$dbcreate' . * TO 'moodle'@'%'`) );

...你有一个你可能不想要的尾随反击。

$dbcreate < MySQL_pristine.sql

......不是你想要的。我想你要做的就是在Perl中读取该文件,并迭代每个包含的SQL语句,对它调用“$ dbh-&gt; do()”。如果你很幸运,那个.sql文件中的每个语句都有一行。