SQLとPHPについて質問です。

現在2つのデータベース間でのデータ処理をしています。

例えば下記の様な2つのデータベースがあります。

★データベース1

テーブル名:TEST1
項目:JOUTAI, KANRI_NO

DBに接続するには

$db_Handle = mysql_connect("aaaaa","bbbb","cccc");
mysql_select_db("dddd");
の命令を使います。

★データベース2

テーブル名:TEST2
項目:KANRI_NO ,KAZU 

DBに接続するには

$db_Handle = mysql_connect("eeeee","ffff","gggg");
mysql_select_db("hhhh");
の命令を使います。

この二つのデータベース間で処理をしたいと考えています。

今回お聞きしたいことですが 

テーブル TEST1 のJOUTAIパラメータが'1'になっているものの管理番号を抜き出し、テーブル TEST2に同じ管理番号があれば項目KAZUに入っている数字に+1を加えるという処理をしたいと考えています。

自分でスクリプトを組んでみたのですがうまくいきませんでした。

お手数をおかけしますが、もしわかるかたおりましたらスクリプトを見ていただければと考えています。

どうぞよろしくお願いします。

回答の条件
  • 1人2回まで
  • 登録:
  • 終了:2009/08/19 16:26:05
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

ベストアンサー

id:kn1967 No.2

回答回数2915ベストアンサー獲得回数301

ポイント100pt

(見直し点1)コネクトは1回

mysql_connect をループ内で毎回行うと、ループした数だけデータベースへの道が作られ、

それぞれ独立したものとして維持管理される事となり、非常に無駄です。

ループ前に1回だけ行うようにします。


(見直し点2)データベースのハンドル名は分ける

ハンドル名が同じだと、後からのものだけが有効となってしまいます。

$db_Handle1 = mysql_connect("aaaaa","bbbb","cccc");

$db_Handle2 = mysql_connect("eeeee","ffff","gggg");


(見直し点3)mysql_select_db、や mysql_query などは省略形にしない。

省略すると「直前の接続だけを使う」事になってしまいますので、

複数同時接続の場合は基本的に省略できません。

$db1 = mysql_select_db("dddd", $db_Handle1);

$abc = mysql_query("SELECT * FROM TEST1 WHERE JOUTAI='1' ", $db_Handle1);

$db2 = mysql_select_db("hhhh", $db_Handle2);

$def = mysql_query("SELECT * FROM TEST2 WHERE KANRI_NO=".$kanri_no." ", $db_Handle2);

mysql_query("UPDATE TEST2 SET KAZU=".$zaiko." WHERE KANRI_NO=".$kanri_no." ", $db_Handle2);


(見直し点4)確認点がない。

接続に成功したかどうかなど、必要な確認を入れていないので、

どこでトラぶっているかの判別が非常に難しくなる。


見直し点はまだまだあり、とてもじゃないけど短文では言い表せないので、

とりあえず大きな点だけあげました。

以下、動作確認までは行っていませんが、極力、元のコードの形をとどめて、

書いてみましたので適宜確認しながら適用していってください。

$db_Handle1 = mysql_connect("aaaaa","bbbb","cccc");
if (!$db_Handle1) {
    echo "データベース1への接続に失敗";
    exit; # 失敗なので、ここで終了
}

$db1 = mysql_select_db("dddd", $db_Handle1);
$abc = mysql_query("SELECT * FROM TEST1 WHERE JOUTAI='1'", $db_Handle1);
$abc_count = mysql_num_rows($abc);
if (!$abc_count) {
    echo "該当するデータは見つかりませんでした。";
    exit; # 書き換えるべきデータは無いので、ここで終了
}

$db_Handle2 = mysql_connect("eeeee","ffff","gggg");
if (!$db_Handle2) {
    echo "データベース2への接続に失敗";
    exit; # 失敗なので、ここで終了
}

$db2 = mysql_select_db("hhhh", $db_Handle2);
while ($row = mysql_fetch_array($abc, MYSQL_ASSOC)) {
    $kanri_no = $row["KANRI_NO"];
    $def = mysql_query("SELECT * FROM TEST2 WHERE KANRI_NO=" . $kanri_no, $db_Handle2);
    while ($row = mysql_fetch_array($def, MYSQL_ASSOC)) {
        $zaiko = $row["KAZU"];
        $zaiko++;
        $u = mysql_query("UPDATE TEST2 SET KAZU=" . $zaiko . " WHERE KANRI_NO=" . $kanri_no, $db_Handle2);
    }
}

※UPDATEに成功したかどうか、何件処理したかについては下記コマンドを参照ください。

PHP: mysql_affected_rows - Manual

id:aiomock

ご回答ありがとうございます。

2009/08/14 11:23:26

その他の回答1件)

id:HALSPECIAL No.1

回答回数407ベストアンサー獲得回数86

ポイント35pt

未確認ですがこちらでいかがでしょうか?



//まずデータベース1で処理するのでデータベース1にアクセスします。
$db_Handle1 = mysql_connect("aaaaa","bbbb","cccc");
mysql_select_db("dddd",$db_Handle1);

//データベース2にアクセスします。
$db_Handle2 = mysql_connect("eeeee","ffff","gggg");
mysql_select_db("hhhh",$db_Handle2);

//状態が1になっているものを選択します。
$abc=mysql_query("SELECT * FROM TEST1 WHERE JOUTAI='1' ",$db_Handle1);

while ($row = mysql_fetch_array($abc, MYSQL_ASSOC)) {

	//管理番号をひとつずつ抜き取って処理していきます。
	$kanri_no=$row["KANRI_NO"];

	//増やした数をデータベース2に反映させます。
	mysql_query("UPDATE TEST2 SET KAZU = KAZU+ 1 WHERE KANRI_NO='$kanri_no'",$db_Handle2);

}


id:aiomock

ご回答ありがとうございます。

2009/08/14 11:23:22
id:kn1967 No.2

回答回数2915ベストアンサー獲得回数301ここでベストアンサー

ポイント100pt

(見直し点1)コネクトは1回

mysql_connect をループ内で毎回行うと、ループした数だけデータベースへの道が作られ、

それぞれ独立したものとして維持管理される事となり、非常に無駄です。

ループ前に1回だけ行うようにします。


(見直し点2)データベースのハンドル名は分ける

ハンドル名が同じだと、後からのものだけが有効となってしまいます。

$db_Handle1 = mysql_connect("aaaaa","bbbb","cccc");

$db_Handle2 = mysql_connect("eeeee","ffff","gggg");


(見直し点3)mysql_select_db、や mysql_query などは省略形にしない。

省略すると「直前の接続だけを使う」事になってしまいますので、

複数同時接続の場合は基本的に省略できません。

$db1 = mysql_select_db("dddd", $db_Handle1);

$abc = mysql_query("SELECT * FROM TEST1 WHERE JOUTAI='1' ", $db_Handle1);

$db2 = mysql_select_db("hhhh", $db_Handle2);

$def = mysql_query("SELECT * FROM TEST2 WHERE KANRI_NO=".$kanri_no." ", $db_Handle2);

mysql_query("UPDATE TEST2 SET KAZU=".$zaiko." WHERE KANRI_NO=".$kanri_no." ", $db_Handle2);


(見直し点4)確認点がない。

接続に成功したかどうかなど、必要な確認を入れていないので、

どこでトラぶっているかの判別が非常に難しくなる。


見直し点はまだまだあり、とてもじゃないけど短文では言い表せないので、

とりあえず大きな点だけあげました。

以下、動作確認までは行っていませんが、極力、元のコードの形をとどめて、

書いてみましたので適宜確認しながら適用していってください。

$db_Handle1 = mysql_connect("aaaaa","bbbb","cccc");
if (!$db_Handle1) {
    echo "データベース1への接続に失敗";
    exit; # 失敗なので、ここで終了
}

$db1 = mysql_select_db("dddd", $db_Handle1);
$abc = mysql_query("SELECT * FROM TEST1 WHERE JOUTAI='1'", $db_Handle1);
$abc_count = mysql_num_rows($abc);
if (!$abc_count) {
    echo "該当するデータは見つかりませんでした。";
    exit; # 書き換えるべきデータは無いので、ここで終了
}

$db_Handle2 = mysql_connect("eeeee","ffff","gggg");
if (!$db_Handle2) {
    echo "データベース2への接続に失敗";
    exit; # 失敗なので、ここで終了
}

$db2 = mysql_select_db("hhhh", $db_Handle2);
while ($row = mysql_fetch_array($abc, MYSQL_ASSOC)) {
    $kanri_no = $row["KANRI_NO"];
    $def = mysql_query("SELECT * FROM TEST2 WHERE KANRI_NO=" . $kanri_no, $db_Handle2);
    while ($row = mysql_fetch_array($def, MYSQL_ASSOC)) {
        $zaiko = $row["KAZU"];
        $zaiko++;
        $u = mysql_query("UPDATE TEST2 SET KAZU=" . $zaiko . " WHERE KANRI_NO=" . $kanri_no, $db_Handle2);
    }
}

※UPDATEに成功したかどうか、何件処理したかについては下記コマンドを参照ください。

PHP: mysql_affected_rows - Manual

id:aiomock

ご回答ありがとうございます。

2009/08/14 11:23:26
  • id:aiomock
    自分は以下のように組んでみました。

    //まずデータベース1で処理するのでデータベース1にアクセスします。

    $db_Handle = mysql_connect("aaaaa","bbbb","cccc");
    mysql_select_db("dddd");

    //状態が1になっているものを選択します。

    $abc=mysql_query("SELECT * FROM TEST1 WHERE JOUTAI='1' ");


    while ($row = mysql_fetch_array($abc, MYSQL_ASSOC)) {

    //管理番号をひとつずつ抜き取って処理していきます。

    $kanri_no=$row["KANRI_NO"];

    //データベース2にアクセスします。

    $db_Handle = mysql_connect("eeeee","ffff","gggg");
    mysql_select_db("hhhh");

    //データベースで同じ管理番号のデータを取り出します。

    $def=mysql_query("SELECT * FROM TEST2 WHERE KANRI_NO=".$kanri_no." ");
    while ($row = mysql_fetch_array($def, MYSQL_ASSOC)) {

    //数の個数に1をプラスします。

    $zaiko=$row["KAZU"];
    $zaiko=$zaiko+1;

    //増やした数をデータベース2に反映させます。

    mysql_query("UPDATE TEST2 SET KAZU=".$zaiko." WHERE KANRI_NO=".$kanri_no." ");

    }


    }

    この命令をしたのですが無理でした。。。
  • id:aiomock
    違うデータベースの間でデータをやり取りする場合はなにか特殊な記載方法みたいなものはあるのでしょうか?

    お手数をおかけしますがよろしくお願いいたします。
  • id:b-wind
    >mysql_connect をループ内で毎回行うと、ループした数だけデータベースへの道が作られ、
    意外にもそうはならない。
    ループ内にあることが無駄であることには変わりないが。

    http://jp.php.net/manual/ja/function.mysql-connect.php
    >同じ引数で 2 回 mysql_connect() をコールした場合、 2 回目は新規のリンクが確立されるのではなく、代わりにすでにオープンされた リンクのリンク ID が返されます。
  • id:aiomock
    //まずデータベース1で処理するのでデータベース1にアクセスします。
    $db_Handle1 = mysql_connect("aaaaa","bbbb","cccc");
    mysql_select_db("dddd",$db_Handle1);

    //データベース2にアクセスします。
    $db_Handle2 = mysql_connect("eeeee","ffff","gggg");
    mysql_select_db("hhhh",$db_Handle2);

    についてですが

    データベース1へはアクセス出来るのですがデータベース2にはアクセスできないという状況が発生しています。

    これはどのように対処すればいいのでしょうか。

    $db_Handle2 = mysql_connect("eeeee","ffff","gggg");
    mysql_select_db("hhhh",$db_Handle2);

    共にエラーを返します。。。
  • id:aiomock
    データベース2へのアクセスが出来れば全て解決できそうです。

    お手数をおかけしますがよろしくお願いします。
  • id:rouge_2008
    データベース1はPHPスクリプトが動作しているレンタルサービスで提供されていて、データベース2はそのサービスとは別のレンタルサービスで提供されているのでしょうか?
    その場合はアクセス不可能だと思います。
    レンタルサーバーのMySQLには、基本的に同じサービスのサーバー内からのアクセスしか許可していない場合が多いようですが、利用しているサービスはどうなっていますか?
  • id:kn1967
    これまでの質問履歴から、オークションとの連携システムを構築するための習作として、
    現在のシステムを構築しているという点は既に理解していますので、
    さくらレンタルサーバ上のデータベースと、自前のパソコン上のデータベースの連携が、
    実は最大の難関であることも当然ながら理解しています。

    理解したうえで、質問に対する直接的回答を行うとともに、
    aiomock氏独自の環境と問題点の両方を考慮して書いたのが回答2です。
    (間違いの訂正ありがとうございました > b-wind 様)

    データベース2への接続に失敗するという問題点をご自身で確認できたようなので、
    ここからは別の話になりますが、以後のヒントとして書いておきます。

    (1)phpプログラムをパソコン上で動かすとなれば、
      サーバ上のデータベースに直接アクセスはできません。
    (2)サーバ上で動かすとなれば、
      パソコン上のデータベースに直接アクセスはできません。

    1についてはサーバ会社のセキュリティ上の措置であるため変更は出来ません。
    2については自前の環境へのアクセスを許可すれば可能にもなりますが、
      個人レベルで外部からの攻撃に対処するのは困難であり、
      現状のスキルではとてもじゃありませんが実現は不可能。

    対策としてはプログラムを2つ用意して連携させるというような手が必要になります。
    (a)データベース1からデータを読み出すphpプログラムを作成してサーバに置く。
    (b)a にアクセスしてデータを受け取り、データベース2に書き込むプログラムを、
      作成してパソコン上に置く。

    サブクエリとかなんとか・・・connectエラーしかチェックしていないのはどうしてとか、
    適当に知っている言葉を並べて口撃を繰り返してくる人もいますが、
    回答の意図を読みきれないのは自身の能力不足だとまだ気づかないのでしょうかねぇ。
    理解できないなら、自分の質問として別途行うべきですし、
    kn1967 の手間を増やして困らせたいだけなら迷惑行為なのだが。
  • id:HALSPECIAL
    HALSPECIAL 2009/08/15 09:32:59
    すみません。能力不足の為、間違えました。
    こうでした。
    mysql_query("UPDATE TEST2 SET KAZU = KAZU+ 1 WHERE KANRI_NO=".$kanri_no,$db_Handle2);


    ハジついでにもう一つ。
    サブクエリという案が出ているのですが、どのようにやるのでしょうか?
  • id:kn1967
    >KAZU = KAZU+ 1

    データの整合性を考えると、
    データベース1から持ってきた値に+1という形のままが良いように思う。
    (これ以前の問題として「接続できない」という大問題があるので、現時点では、
    あまり意味の無い事だけど、意識はしておくべきだと思うから書きました。)

    それにしてもサブクエリの御仁(id:kmond2)はどうしたのでしょうねぇ。

  • id:HALSPECIAL
    HALSPECIAL 2009/08/16 00:30:22
    >id:aiomockさん

    アクセスできないと言われるデータベース2は、どのような環境下にあるのですか?

    共にエラーを返します。。。との事ですが、どのようなエラーを返すのですか?


    どのような質問でもそうですが、
    「エラーになる」とか「アクセスできない」
    といった情報提供だけでは、回答する側としては想像の域を出ることができません。
    (ユーザーさんに多いです)


    つうか、エラーが表示されるのであれば、その通りなんだと思いますよw


    そのあたりを明示すれば解決されるかもしれませんね。
    (私は知識不足で無理かもしれませんが^^;)


  • id:aiomock
    ご回答皆さん本当にありがとうございます。

    本日サクラサーバーの会社へ問い合わせてみたところ、サクラサーバーでは基本的に他のサーバーとの接続は出来ないとのことです。

    自分は同じ名義でもうひとつサーバーを持っているのですがそことの接続も出来ませんでした。

    同じ会社でもサクラサーバーの場合はDBのデータのやり取りが基本的には不可能のようです。

    という事で大変申し訳ありませんが、今回の処理についてはあきらめようと思います。

    大変面倒ですがデータベース1の中に処理できるテーブルを作って、その中にデータを入れた後、処理を施す事にします。

    データベース間での処理がしたいと思ったのですが、今の自分の環境・技術力だと出来そうにないので少しショックです。。

    与えられたサービスだとその中だけでしか処理が出来ないのでやはり自分である程度のものを作りたいと思ったら、やはり自分でサーバーを作って、その中で処理を施していくしかないと考えています。

    現在は自作サーバーとデータベースの処理は考えていないのですが、もし今後そういう機会があればセキュリティ面ではすごい不安がありますが、誰にもURL を教えず、Google等の検索候補にひっかかることもなく、誰からも絡まれず、ひっそりとデータベース間処理をやりたいのですがネット上でなるべく存在を消してDB処理を施すというのは可能でしょうか?
  • id:aiomock
    回答していただいた皆さんは処理が施されているということは

    自宅や会社でのデータベース間処理が出来る環境が整っているということでしょうか?

    もし素人でも出来るお勧めの環境などありましたら教えていただきたいです。
  • id:kn1967
    同一契約者でも別のデータベースへのアクセスを禁じてるのは、
    さくらに限らず当然だったりもしますので、
    どうしても複数のデータベースが必要になる場合は、
    ・1つの契約の中で複数のデータベースを作成できるようなサーバーを借りる
      sakuraならばスタンダードではなく
      ビジネス(2つまで)/ビジネスプロ(3つまで)コースへ乗り換える。
    ・専用サーバー(あるいはVPSサーバ)を借りる
      値段はかなり高くなりますが、制限はほぼなくなります。
    ・自宅サーバを構築する
      学習しなければならない範囲は広大なものとなり、
      データベース構築・維持どころではなくなってきます。
    といったようなチョイスが必要になってきます。

    >誰からも絡まれず、ひっそりとデータベース間処理をやりたい

    「インターネットは開く事が前提の世界」なので隠すのは非常に難しい。
    どうしても繋ぐ必要があるのならば、専用線やVPN等を準備して、
    他の回線からは一切接続できないようにしておいてから、
    サーバーのポートを開放するといったような工夫が必要になります。
    (結局のところ、お金をかければ出来るけど・・・となってしまいます)

    >大変面倒ですがデータベース1の中に処理できるテーブルを作って、
    >その中にデータを入れた後、処理を施す事にします。

    現時点においては、それが最善の策かもしれません。

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません