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

MySQL 3.23.49-nt を使用中です。
とあるテーブルを、3つのサーバで使用中で、このテーブルを一つのサーバで更新して、他のサーバへ
レコードをコピーしたいのですが、「他のサーバ」に既に同じキーの
レコードが存在する可能性があります。

こちらで更新したいサーバ(A)のテーブルの内容をこんな感じだとします。
キー番号 | SEQ | 項目A | 項目B
---------+-----+-------+------
1001 | 1 | 11-AA | 11-BB
1001 | 2 | 12-AA | 12-BB
1002 | 1 | 21-AA | 21-BB
1002 | 2 | 22-AA |

そして、コピー先のサーバ(B)のテーブルの内容をこんな感じだとします。
キー番号 | SEQ | 項目A | 項目B
---------+-----+-------+------
1001 | 1 | 11-BA | 11-XX
1002 | 1 | 21-BA | 21-YY
1002 | 2 | | 22-YY

「キー番号」「SEQ」「項目A」だけを、サーバAと同一にしたいと考えています。
キー番号とSEQが同一のレコードが存在する場合、サーバBの「項目B」は変えたく
ありません。

すなわち、サーバ(B)が
キー番号 | SEQ | 項目A | 項目B
---------+-----+-------+------
1001 | 1 | 11-AA | 11-XX ---- 項目Aを更新
1001 | 2 | 12-AA | ---- レコードをINSERT
1002 | 1 | 21-AA | 21-YY ---- 項目Aを更新
1002 | 2 | 22-AA | 22-YY ---- 項目Aを更新
のようになって欲しいのです。

そこで、
「キー番号="1001"、SEQ = "1" のレコードがあれば、そのレコードの項目Aに'11-AA'をセットしてUPDATE。
レコードがなければ、キー番号="1001"、SEQ = "1"、項目A='11-AA'のレコードをINSERT。」
というようなMySQLの命令文(?)を書けないかなぁ?と、一生懸命参考書をひっくり返してもがいています。
できるようなできないような...
無理でしょうか?

A 回答 (4件)

プログラムを使わないで、MySQLのコマンドだけでですか?



簡単な方法としては一度、全部のデータをinsertしてから全部のデータをupdateすれば良いと思います。
※キー番号とSEQがプライマリKEYになっている前提で

1.全部のデータをinsert
 →1001/2のデータ以外はエラーになって更新されない。
2.全部のデータをupdate
 →1001/2を含む全データがupdateされる。

この回答への補足

連休を挟んでしまって遅くなり失礼しました。
「エラー承知でいったん全部Insertして...」と言うアイディアに、「目からウロコ!」とは思ったのですが...

結論から言うと、「やっぱりエラーなしでやりたい」です。
理由は二つあります。
1.他の2つのサーバへの処理は他の人に依頼するので、エラーが出ると不安がられる。
2.SQLをファイルに保存して、Dosでのコンソールから実行すると、エラーが発生した行で停止してしまう。
Windows上のSQL実行ソフトでやれば、エラー発生も警告表示だけで先に進んでくれるんですが...
やっぱりMySQLのコマンドだけでは無理なのでしょうかね。

補足日時:2004/05/10 01:16
    • good
    • 0

うーん、他の人からの回答が無いところ見るとSQLコマンドだけでは無理かもしれないですね。


私も分かりません^^;

補足を読んだ感じでアドバイスですが、
Tues17さんが1つのサーバを管理していて、他の2つのサーバ管理者にSQLファイルを送っているようですが、
それならば、他管理者へは直接出来上がったDBファイルを送れば済みそうですがどうでしょう?

Windowsサーバですと、c:\mysql\data\DB名\下に
テーブル名のファイルが3つあります。
それをそのまま送って同じ場所に上書きコピーすればOKです。

これならばTues17さんだけエラーを我慢すればすみます(笑)

この回答への補足

回答ありがとうございます。
おっしゃるとおり、私だけがエラーを我慢すればOKならそうするのですが...サーバBと同様なサーバCがさらに別の場所(別の管理者のところ)にあって、そこのデータも「なければInsert、あればUpdate」したいのです。Updateする場合は、Updateしたくない項目もあるので...
#1でいただいたアドバイスを元に、「まず全件Insertしてみる」路線で頑張っています。Insertの「IGNORE」オプションが使えるのでは?とこの週末に自宅でSQLを試してみるつもりだったのですが、体調不良で果たせませんでした...
また結果をご報告します。

補足日時:2004/05/17 01:25
    • good
    • 0
この回答へのお礼

項目によって、こちらから送った値を生かしたい項目と、先方のサーバの値を生かしたい項目が混在しているので、やっぱりテーブルのファイルをそのまま送るのはダメなんです...

結局、補足に書いたとおり、Insert IGNORE + Update で対処できました。
どうもありがとうございました。
#1にポイントを上げておきますね...

お礼日時:2004/05/19 01:29

どこまでお望みのことができるかどうかは分かりませんが、REPLACE INTOを使ってはできないでしょうか?



たぶん「MySQL REPLACE INTO」とでも検索すれば、使い方は出てくると思います。
#INSERTと似てますけど・・・

間違いがありましたらご指摘ください。
ではでは☆
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。
残念ながら、REPLACE INTO は今回の私の要求には合わないようです。
(『REPLACE は INSERT とほぼ同じように動作しますが、唯一異なる点として、UNIQUE インデックスまたは PRIMARY KEY に
関して新しいレコードと同じ値がテーブル内の以前のレコードに含まれていると、以前のレコードが削除されてから新しい
レコードが挿入されます。 』というやつですよね?)

キー番号「1001」SEQ「1」のレコードについて、REPLACE INTOを使うと、
サーバBの値は項目A:「11-AA」項目B:「11-BB」となってしまいますよね?
でも、サーバBのこのレコードの項目Bは、もともとの「11-XX」を残して、
項目Aの「11-BA」だけを、サーバAに合わせて「11-AA」に上書きしたいのです。

今回は、#2に書いたように、「Insert IGNORE」+「Update」の組み合わせで更新できました。

KanataさんにアドバイスいただいたReplace into は全然知らなかったのですが、今後の参考にさせていただきます。勉強になりました。

お礼日時:2004/05/19 01:32

うわ、こんなコマンドあったんだ^^;


Kanataさん便乗でありがとうございました。
私も全部作り直しします(苦笑)

Tues17さん、すみませんでした。
    • good
    • 0
この回答へのお礼

いえいえ、どういたしまして...って私が教えたわけではないのですが ^^;
私ももうちょっとMySQLのコマンドを勉強します。
Kanataさん、R34_666さん、どうもありがとうございました。

お礼日時:2004/05/19 01:34

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