2011-08-03 16 views
0

私はPerlを初めて使い、RHELボックスにスクリプトを書き込もうとしました。このスクリプトは、私たちがホスト上に作成した新しいサイト用のバニラDBを自動設定します。私はすでに接続ステートメントが働いていると私は接続し、スクリプトからDBを作成することができる(使用して$ dbh - > do(qq(CREATE DATABASE $ dbcreate));これは最善の方法ですか?私はそれらを動作させる方法を理解することができていないカップルを持っている。Perlスクリプトがmysqlコマンドを実行していますか?

これは私が問題を抱えている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

DBIを使用している場合、なぜmysqlシェルと対話的に作業しようとしていますか?あなたの質問の最初の半分はPerlを扱い、後半はファイルをコマンドラインツール 'mysql'にリダイレクトすることです。あなたのサンプルコードにはPerlはありません。また、あなたは何を持っているのか説明していません。私たちは推測すべきでしょうか? – DavidO

+0

これらの文はすべて 'DBI'から正常に動作し、' $ dbh-> do() 'から実行できます。エラーメッセージが表示されている場合は、それらを投稿してください。もう少しPerlを投稿してください。あなたが掲示した単一の声明にはいくつかのリスクがありますが、文脈が存在しなければ私たちが助けることはあまりありません。文字列を間違って引用すると(つまり、 'q {} 'ではなく' qq {} 'で)補間される可能性のある' @ 'を使用することが考えられます。 –

+0

@morungos私は以下のエラーと一緒に試したコードを含めるために投稿を編集しました。あなたは@記号について正しいと思います。 – Brandon

答えて

0

あなたが遭遇した主な問題は、アットマークを含む文字列の補間です。 qq{Here is my email: [email protected]}のようなものがあれば、これは存在しないリスト変数@hotmailを置こうとするので失敗します。バックスラッシュを使用してエスケープするか(つまりqq{Here is my email: test\@hotmail.com})、変数を補間する必要がない場合は、補間しない見積もりq{...}を使用してください。

これらの記述の中には、これらの記述のいくつかに少し注意する必要があります。これらのSQL文には可変の値を入れています。これはSQLインジェクション攻撃のリスクです。私は$dbh->quote($dbcreate)を使用して文字列のバージョンを取得し、の値の識別子バージョンを取得し、それらの値を埋め込みます。これは、あなたがBobby Tablesをやっている誰かを避け、データベース名はdb'; DROP TABLE mysql.user; ';または類似しています。 DBIは文字列と識別子の両方の引用符を提供するので、必要に応じて正しい種類の引用符を得ることができます。たとえば:

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

プレースホルダは、通常は優れているが、これらの管理文のいくつかは、おそらくそうな値を注入するために引用し、適切な使用して、それらをサポートしません必要である可能性が高いです。

+0

ありがとうございます、これは現在意図したとおりに動作しています!私は、Webアクセスできないディレクトリのコマンドラインから実行され、rootだけがファイルをrwxできるので、何らかの注射について心配する必要はありません。私のコードは一番うまくいっていないと確信していますが、それは仕事を終わらせます。再度、感謝します! – Brandon

0

2つのことが私に目立ちます。

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

...あなたはおそらく意図していない末尾のバックティックを持っています。

$dbcreate < MySQL_pristine.sql 

...あなたが望むものではありません。私はあなたがしようとしていると思うのは、そのファイルをPerlで読み込み、そこに含まれる各SQL文を繰り返し処理し、 "$ dbh-> do()"を呼び出すことです。非常に運が良ければ、その.sqlファイルに1つの文が1行ずつあります。

関連する問題