简体   繁体   English

Perl脚本执行mysql命令?

[英]Perl script executing mysql commands?

I'm new to Perl and was attempting to write a script on a RHEL box that will auto-configure a vanilla DB for new sites we create on our host. 我是Perl的新手,正在尝试在RHEL框上编写脚本,该脚本将为我们在主机上创建的新站点自动配置Vanilla DB。 I already have the connect statement working and I'm able to connect and create a DB from the script (Used $dbh->do( qq(CREATE DATABASE $dbcreate) ); Is this the best way???), but I have a couple that I haven't been able to figure out how to make them work. 我已经有了connect语句,并且可以通过脚本连接并创建数据库(使用$ dbh-> do(qq(CREATE DATABASE $ dbcreate));这是最好的方法吗?),但是我有一对我无法弄清楚如何使它们工作的夫妇。

These are the mysql commands which I'm having issues with. 这些是我遇到问题的mysql命令。 Any suggestions? 有什么建议么? Thanks! 谢谢!

$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.

The main issue you've encountered is interpolation of strings with containing an at-sign. 您遇到的主要问题是包含符号的字符串插值。 If you have something like qq{Here is my email: test@hotmail.com} - this fails because it tries to put a list variable @hotmail , which doesn't exist. 如果您有类似qq{Here is my email: test@hotmail.com} -因为它试图把一个列表变量失败@hotmail ,它不存在。 Either use a backslash to escape it (ie, qq{Here is my email: test\\@hotmail.com} ), or if you don't need to interpolate any variables, use the non-interpolating quote q{...} . 请使用反斜杠将其转义(即qq{Here is my email: test\\@hotmail.com} ),或者,如果不需要插值任何变量,请使用非插值引号q{...}

Having said that, you need to be a little careful with some of these statements. 话虽如此,您需要对其中的一些声明有所注意。 You're putting variable values into these SQL statements, and that is a risk for SQL injection attacks. 您正在将变量值放入这些SQL语句中,这会带来SQL注入攻击的风险。 I'd use $dbh->quote($dbcreate) to get a string version, and $dbh->quote_identifier($dbcreate) to get an identifier version of the value of $dbcreate , and embed those values in. This is much safer, as it will avoid somebody doing a Bobby Tables on you and giving you a database name like: db'; DROP TABLE mysql.user; '; 我将使用$dbh->quote($dbcreate)获取字符串版本,并使用$dbh->quote_identifier($dbcreate)获取$dbcreate值的标识符版本,并将这些值嵌入其中。更安全,因为它将避免有人对您执行Bobby Tables并为您提供数据库名称,例如: db'; DROP TABLE mysql.user; '; db'; DROP TABLE mysql.user; '; or similar. 或类似。 DBI provides both string and identifier quoting, so you can get the right kinds of quoting as needed. DBI提供了字符串和标识符引号,因此您可以根据需要获得正确的引号。 For example: 例如:

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

Placeholders are usually better, but some of these admin statements probably won't support them, so using proper quoting to inject the values is likely to be necessary. 占位符通常更好,但是其中一些admin语句可能不支持它们,因此可能有必要使用正确的引号注入值。

Two things stand out to me. 两件事对我很重要。

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

...you've got a trailing backtick that you probably don't intend. ...您可能不希望有一个倒叙。

$dbcreate < MySQL_pristine.sql

...isn't quite what you want. ...不是您想要的。 I think you're trying to do is to read that file in Perl, and iterate over each contained SQL statement, calling "$dbh->do()" against it. 我认为您要尝试的是在Perl中读取该文件,并遍历每个包含的SQL语句,然后对它调用“ $ dbh-> do()”。 If you're very lucky, you have one line per statement in that .sql file. 如果您很幸运,那么该.sql文件中的每个语句只有一行。

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

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