プロが教える店舗&オフィスのセキュリティ対策術

お疲れ様です。
お世話になります。

データベースにあるキーを基にSELECTを出して、該当レコードがあればそのレコードのIDを取得、
なければ、そのキーをINSERTして、INSERT_IDを取得する。

これをひとつのクエリでできないかと悩んでいます。
perlだとfind_or_createというメソッドがあるらしいのですが、
私はPHP書きです。
DBはMySQL5を使っています。
PHPも5xです。

ググってもあまりいい案はなく、ムリならムリと突きつけていただければ
2つのクエリでがんばります。

よろしくお願いします。

A 回答 (2件)

>そのキーをINSERTして、INSERT_IDを取得



auto_incrementを使うということですか?
auto_increment指定列と、もう一つ別のユニークなキーがあり、そのキーで検索するということでしょうか?

#1の例のauto_increment版です。

1.テスト用表定義
create table t1
(c1 int primary key auto_increment,
c2 char(1),
c3 varchar(10));
create unique index t1ix1 on t1(c2);

2.テスト用初期データ
insert into t1(c1,c2) values(null,'a'),(null,'b');

3.ストアドプロシジャの定義
drop procedure if exists find_or_create; -- 存在したら削除
delimiter // -- 終端記号の変更
create procedure find_or_create
(in pKey char(1),
out pInsertID int,
out pRC int)
--
-- 存在したらキー値を返し、存在しなかったら追加
--
begin

set pRC=0,pInsertID=null;
-- 検索してみる
select c1
into pInsertID
from t1
where c2=pKey;
if pInsertID is null then
-- 存在しなかったら追加
insert into t1(c1,c2)
values(null,pKey);
-- LastInsertIDを取得
select last_insert_ID()
into pInsertID;
set pRC=4;
end if;
end;
//
delimiter ; -- 終端記号を元に戻す

4.テスト
call find_or_create('c',@InsertID,@rc);
select @InsertID,@rc;
call find_or_create('c',@InsertID,@rc);
select @InsertID,@rc;
call find_or_create('d',@InsertID,@rc);
select @InsertID,@rc;
call find_or_create('a',@InsertID,@rc);
select @InsertID,@rc;
    • good
    • 0
この回答へのお礼

ご丁寧な回答ありがとうございます。
ソースまで書いていただいて、頭の下がる思いです。

INSERT_IDはauto_incrementのつもりでした。
ストアドプロシージャは使ったことがないんですが、
これをきっかけに勉強してみます。

ありがとうございました。

お礼日時:2007/07/27 09:24

find_or_createについて少し検索してみましたが、分かりやすい記事が見つけられませんでした。



MySQL5なら、ストアドプロシジャで類似機能を実装する方法もあります。

1.テスト用の表定義
create table t1
(c1 int primary key,
c2 int,
c3 varchar(10));

2.テスト用の初期データ
insert into t1(c1) values(1),(10);

3.ストアドプロシジャ登録
drop procedure if exists find_or_create; -- 存在したら削除
delimiter // -- 終端記号の変更
create procedure find_or_create
(in pInKey int,
out pOutKey int,
out pRC int)
--
-- 存在したらキー値を返し、存在しなかったら追加
--
begin

set pRC=0,pOutKey=null;
-- 検索してみる
select c1
into pOutKey
from t1
where c1=pInKey;
if pOutKey is null then
-- 存在しなかったら追加
insert into t1(c1)
values(pInkey);
-- 再検索してもいいが、変数間でコピー
set pOutKey=pInKey;
set pRC=4;
end if;
end;
//
delimiter ; -- 終端記号を元に戻す


4.ストアドプロシジャのテスト
call find_or_create(50,@key,@rc);
select @key,@rc;

※既に存在したら@rc=0、追加したら@rc=4、@keyにそのキー値が返ります。
    • good
    • 0
この回答へのお礼

#2のほうを実行してみました。
見事find_or_createできてました。

すごいです。自分にとっちゃ新発見でした。
感動しました。

ありがとうございました!

お礼日時:2007/07/27 10:03

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