我是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.
答案 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文件中的每个语句都有一行。