アプリ版:「スタンプのみでお礼する」機能のリリースについて

今、テキストデータをpostgreSQLのデータベースに一括インポートする
CGI(perl)にて作成中なのですが、息詰まってしまい、わかる方が
いましたら、ご伝授いただければと思い質問させていただきました。

■CGI(test-inport.cgi)

   ~ 省略 ~

$cmd = "●●●";
system($cmd);

$cmd = "psql -h ホスト名 -c 'copy テーブル名 from 'テキストファイル名'";
system($cmd);

※ここのホスト名は何を書いたらいいのでしょうか?
良かったら、教えて下さい。

上記ので、●●●に、telnet で使用する
\i テーブル名
などを入れて、DBを作成し、そこにテキストデータを流したい
と思っています。

しかし、
$cmd = "\i テーブル名";
system($cmd);

が動きません。

どのように、書けばいいのでしょうか?
良かったら、教えて下さい。
また、アルゴリズム自体がおかしい場合は、
違う手法も教えていただければと思います。

A 回答 (5件)

connectしてからdisconnectするまでの間はいくつでもSQL文を実行してもよいのでループを使うのはいっこうに構いません。


要はSQL文の文法(構文)さえあっていればOKです。

ところで、ファイルハンドルを元に一行ずつ読み出すのに使うのは、
while<FILE>{
ではなくて
while(<FILE>){
となります。
    • good
    • 0
この回答へのお礼

DBIという方法があることを
初めて知ったにも関わらず、丁寧に回答して
いただいて、本当にありがとうございます。
教えていただいた方法で作成してみようと
思います。
有難うございました。

お礼日時:2004/10/04 22:32

訂正


$db->disconnect; #切断
は正しくは
$dbi->disconnect; #切断
です。
「i」が抜けてました。
    • good
    • 0

$dbi = DBI->connect("dbi:Pg:dbname=データベース名;host=SQLサーバーのホスト名", $user, $password);



$sql = "INSERT INTO table(foo,bar,baz) VALUES (?,?,?)";

$sth = $dbi->prepare($sql); #文の実行準備
$sth->execute; #実行
$sth->finish; #終了

$db->disconnect; #切断

↑をdoを使うと↓のようにできます。

$dbi = DBI->connect("dbi:Pg:dbname=データベース名;host=SQLサーバーのホスト名", $user, $password);

$sql = "INSERT INTO table(foo,bar,baz) VALUES (?,?,?)";

$dbi->do($sql); #文の実行準備・実行・終了

$db->disconnect; #切断

この回答への補足

とてもわかりやすい回答有難うございます。
テキストデータを繰り返して、
INSERTする場合は、
$dbi = DBI->connect("dbi:Pg:dbname=データベース名;host=SQLサーバーのホスト名", $user, $password);

while<FILE>{
$sql = "INSERT INTO table(foo,bar,baz) VALUES (?,?,?)";

$dbi->do($sql); #文の実行準備・実行・終了
}
$dbi->disconnect; #切断

とすれば良いのでしょうか?
また、foo,bar,bazが決まっていない場合、

$dbi = DBI->connect("dbi:Pg:dbname=データベース名;host=SQLサーバーのホスト名", $user, $password);

$tmp = "foo,bar,baz";
$tmp2 = "?,?,?";

while<FILE>{
$sql = "INSERT INTO table($tmp) VALUES ($tmp2)";

$dbi->do($sql); #文の実行準備・実行・終了
}
$dbi->disconnect; #切断

とすれば、それぞれ違うテーブルに対して、
データをinsertした場合、使えますでしょうか?

良かったら教えてください。

補足日時:2004/10/03 21:20
    • good
    • 0

> while(<CSV>) {


> chop;
> my ($foo,$bar,$baz) = split /,/;
> $sth->execute($foo,$bar,$baz);
> }

executeのみ連続でしようするということはできません。
prepareとexecuteは対です。

なお、INSERTのようにSELECTで内容を取ってくるような命令でなければ、doを使うこともできます。

doを使うとprepareとexecuteとfinishが順番にすぐ行われたことになります。

この回答への補足

すみません。doを使うとは、どのように
使えばいいのでしょうか?
良かったら教えてください。

補足日時:2004/10/02 20:45
    • good
    • 0

というか、DBI等のモジュールは使わないんですか?


system関数で呼ぶというのはスマートな方法とはいえないですが・・・。
(DBIとはデータベースにアクセスするためのPerl言語によるAPIのことです。)
ちなみにPostgreSQLへの接続の場合はDBD::Pgと併用することになります。
少なくともsystem関数でいちいち呼ぶよりは格段に扱いやすくなります。
(自分の場合はMySQLサーバーとの接続にDBI/DBDを使っています)



use DBI;

$dbi = DBI->connect("dbi:Pg:dbname=データベース名;host=SQLサーバーのホスト名", $user, $password ); #PostgreSQLサーバーへ接続

$sql = "select * from TABLE"; #文の用意
$result = $dbi->prepare($sql); #文の実行準備
$result->execute; #実行

while(@rows = $result->fetchrow_array ) { #結果取得ループ
結果(select結果)を取得して煮るなり焼くなりの処理
}

$dbi->disconnect; #PostgreSQLサーバーから切断

この回答への補足

回答有難うございます。
DBI等のモジュールというのを初めて知りましたので、
教えていただいた方法で、行ってみようと
思うのですが、したいことは、一括登録になるので、
insert処理をしたいと思っています。
この場合、教えていただいた方法を参考に作成して
みたのですが、このような感じで動くものでしょうか?
教えてください。

<案>
use DBI;

$dbi = DBI->connect("dbi:Pg:dbname=データベース名;host=SQLサーバーのホスト名", $user, $password ); #PostgreSQLサーバーへ接続

$sth = $dbh->prepare(
"INSERT INTO table(foo,bar,baz) VALUES (?,?,?)"
);

while(<CSV>) {
chop;
my ($foo,$bar,$baz) = split /,/;
$sth->execute($foo,$bar,$baz);
}

$dbi->disconnect; #PostgreSQLサーバーから切断

補足日時:2004/10/02 01:41
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!