C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[2]: 新規登録と更新を併せたSQL文の書き方


(過去ログ 39 を表示中)

[トピック内 12 記事 (1 - 12 表示)]  << 0 >>

■20565 / inTopicNo.1)  新規登録と更新を併せたSQL文の書き方
  
□投稿者/ キキ (7回)-(2008/06/12(Thu) 15:15:57)

分類:[.NET 全般] 

度々申し訳ありません!!ストアド内でSQL文を使い、新規登録と更新を1つの条件として記述する事はできないでしょうか・・・
INSERT INTO DEPT(CODE,NAME)VALUES(CODEA,NAMEA);
UPDATE DEPT SET NAME = NAMEA WHERE CODE = CODEA;
↑現在こんな感じなのですが、新規登録も更新もフォームが同じ画面なので
入力したコードがあらかじめテーブルに登録されているコードと重複したら下の動作を行いたいのですが、どう記述したらいいか教えて下さい;;
引用返信 編集キー/
■20566 / inTopicNo.2)  Re[1]: 新規登録と更新を併せたSQL文の書き方
□投稿者/ επιστημη (1081回)-(2008/06/12(Thu) 15:22:18)
επιστημη さんの Web サイト
UPDATEを試み、その結果UPDATEされたレコードがなければINSERT、でしょうか。
# ORACLEにはMERGE INTO... てのがあるそうな

引用返信 編集キー/
■20571 / inTopicNo.3)  Re[2]: 新規登録と更新を併せたSQL文の書き方
□投稿者/ はまや (35回)-(2008/06/12(Thu) 16:05:38)
No20566 (επιστημη さん) に返信
> UPDATEを試み、その結果UPDATEされたレコードがなければINSERT、でしょうか。
> # ORACLEにはMERGE INTO... てのがあるそうな

楽観的更新時を考慮して、timestampとかをWHEREに追加している場合は、
更新行が0で返ってくるので、その場合はレコードがあって更新しなかったのか
レコードが無くて更新できなかったのかを判断しなくてはならないかと思います。

その場合は、SELECT文でCODEA検索した結果にてIF〜ELSEした方が良いと思います。

引用返信 編集キー/
■20574 / inTopicNo.4)  Re[3]: 新規登録と更新を併せたSQL文の書き方
□投稿者/ 鶏唐揚 (190回)-(2008/06/12(Thu) 16:13:08)
No20571 (はまや さん) に返信
> ■No20566 (επιστημη さん) に返信
>>UPDATEを試み、その結果UPDATEされたレコードがなければINSERT、でしょうか。
>># ORACLEにはMERGE INTO... てのがあるそうな
>
> 楽観的更新時を考慮して、timestampとかをWHEREに追加している場合は、
> 更新行が0で返ってくるので、その場合はレコードがあって更新しなかったのか
> レコードが無くて更新できなかったのかを判断しなくてはならないかと思います。
>
> その場合は、SELECT文でCODEA検索した結果にてIF〜ELSEした方が良いと思います。
>
ストアドじゃない話で申し訳ないのですが、私も
プログラム中からSQL発行する場合に、更新対象を抽出できる条件でいったんSELECTして、
ゼロ件だったらINSERT、そうでなかったらUPDATEするようにしてます。

これならば更新対象はおそらく1件だと思うので時間もかからないはずですし、
応用性があるのでお勧めします。

プログラムでの応用例:
フラグによって更新対象未存在時の挙動を、
「エラー」とするか「追加」とするか変更できる 等
引用返信 編集キー/
■20579 / inTopicNo.5)  Re[4]: 新規登録と更新を併せたSQL文の書き方
□投稿者/ キキ (9回)-(2008/06/12(Thu) 16:36:30)
> ■No20571 (はまや さん) に返信
ありがとうございます!IF文にした場合、

IF DEPT.CODE = CODEA THEN
UPDATE DEPT SET NAME = NAMEA;
ELSE IF
INSERT(CODE,NAME)VALUES(CODEA,NAMEA);
END IF
COMMIT;
こうですかね・・・

>>■No20566 (επιστημη さん) に返信
> >>UPDATEを試み、その結果UPDATEされたレコードがなければINSERT、でしょうか。
> >># ORACLEにはMERGE INTO... てのがあるそうな
ありがとうございます。その場合、

MERGE INTO DEPT
WHEN MATCHED THEN
UPDATE SET NAME = NAMEA
WHEN NOT MATCHED THEN
INSERT (CODE,NAME)
VALUES (CODEA,NAMEA) ;
COMMIT;

となるのでしょうか^^;

No20574 (鶏唐揚 さん) に返信

SELECT文で検索してからINSERTやUPDATEしているんですね。
更新条件・・・というのがちょっとわからないです;;ごめんなさい!
引用返信 編集キー/
■20595 / inTopicNo.6)  Re[5]: 新規登録と更新を併せたSQL文の書き方
□投稿者/ はつね (778回)-(2008/06/12(Thu) 17:34:51)
はつね さんの Web サイト
No20579 (キキ さん) に返信
> IF DEPT.CODE = CODEA THEN
> 		UPDATE DEPT SET NAME = NAMEA;
> ELSE IF
> 		INSERT(CODE,NAME)VALUES(CODEA,NAMEA);
> END IF
> 		COMMIT;
> こうですかね・・・

PL/SQLの例(1):
BEGIN
  INSERT INTO DEPT (CODE,NAME)VALUES(CODEA,NAMEA);
EXCEPTION
WHEN OTHERS THEN
  UPDATE DEPT SET NAME=NAMEA WHERE CODE=CODEA;
END;
/

PL/SQLの例(2):
DECLARE
  CURSOR curDEPT IS SELECT * FROM DEPT WHERE CODE=CODEA;
  recDEPT curDEPT%ROWTYPE;
BEGIN
  OPEN curDEPT;
  FETCH curDEPT INTO recDEPT;
  IF curDEPT%FOUND THEN
    UPDATE DEPT SET NAME=NAMEA WHERE CODE=CODEA;
  ELSE
    INSERT INTO DEPT (CODE,NAME)VALUES(CODEA,NAMEA);
  END IF;
  CLOSE curDEPT;
END;

>>>># ORACLEにはMERGE INTO... てのがあるそうな
> ありがとうございます。その場合、

MERGE INTO DEPT
USING (
	SELECT * FROM DEPT WHERE CODE=CODEA
) DUMMY
ON (DEPT.CODE = DUMMY.CODE)
WHEN MATCHED THEN
    UPDATE SET 
      NAME=DUMMY.NAMEA
WHEN NOT MATCHED THEN
    INSERT INTO DEPT (CODE,NAME) VALUES (DUMMY.CODEA,DUMMY.NAMEA);

※コードは全て未検証です。

引用返信 編集キー/
■20596 / inTopicNo.7)  Re[5]: 新規登録と更新を併せたSQL文の書き方
□投稿者/ eternia (19回)-(2008/06/12(Thu) 17:40:50)
No20579 (キキ さん) に返信
>
> IF DEPT.CODE = CODEA THEN
> UPDATE DEPT SET NAME = NAMEA;
> ELSE IF
> INSERT(CODE,NAME)VALUES(CODEA,NAMEA);
> END IF
> COMMIT;
> こうですかね・・・

えっと、これだとUPDATEでデータが全部更新されちゃいます。
あとIFでDEPT.CODEってできないんじゃないかな。

CODEAを条件にUPDATEした後で SQL%ROWCOUNT が0ならINSERTとかでいけるかと。
※ORACLEの場合です。SQLServerなら @@ROWCOUNT かな?

> ありがとうございます。その場合、
>
> MERGE INTO DEPT
> WHEN MATCHED THEN
> UPDATE SET NAME = NAMEA
> WHEN NOT MATCHED THEN
> INSERT (CODE,NAME)
> VALUES (CODEA,NAMEA) ;
> COMMIT;
>
> となるのでしょうか^^;

比較する対象がないです。
DUALとかでいいんでCODEAの条件をつけてあげないとダメですね。

> SELECT文で検索してからINSERTやUPDATEしているんですね。
> 更新条件・・・というのがちょっとわからないです;;ごめんなさい!

CODE = CODEA のことです。

引用返信 編集キー/
■20598 / inTopicNo.8)  Re[6]: 新規登録と更新を併せたSQL文の書き方
□投稿者/ キキ (10回)-(2008/06/12(Thu) 18:11:59)
はつねさん!無事動きました!
エラーを出す時等の参考にもなりました!有難うございます!!

eterniaさん!

IF文を使った形が間違えてるようなのですが…


SELECT CODE = CODEA FROM DEPT;

IF TRUE THEN
UPDATE DEPT SET NAME=NAMEA WHERE CODE=CODEA;
ELSE
INSERT INTO DEPT (CODE,NAME)VALUES(CODEA,NAMEA);

END IF;


あれれ…TRUEで判断すればいいのでしょうか…
何か間違いだらけだと思うのですが、教えて頂けたら嬉しいです;;
引用返信 編集キー/
■20599 / inTopicNo.9)  Re[7]: 新規登録と更新を併せたSQL文の書き方
□投稿者/ はまや (36回)-(2008/06/12(Thu) 18:17:27)
ごめんなさいm(__)m
なんか書式が違うな〜と思ったらORACLEでしたか(前の書き込みで確認しました)
SQL Serverしかまだ知らないんです....

なので理屈だけかくと
SELECT文等は、実行した結果の行数が返ってきます。
最初にSELECT文で SELECT code FROM DEPT WHERE code = 'CODEA' を実行すると
存在しなかった場合0が返ってきます。 IFはその結果と比較します。
0だったらINSERT、1以上ならUPDATE。

つまり、ORACLEで(直前の処理)結果がSQL%ROWCOUNTに入ってくるなら
こうですかね?
SELECT code FROM DEPT WHERE code = 'CODEA'
IF SQL%ROWCOUNT <> 0 THEN
UPDATE DEPT SET NAME = NAMEA WHERE CODE = CODEA;
ELSE IF
INSERT INTO DEPT(CODE,NAME)VALUES(CODEA,NAMEA);
END IF
COMMIT;

自分が書いたのは、あくまでも楽観的更新を考慮した対応がされている場合なので
UPDATEのWHERE文がWHERE CODE = CODEAだけなら

UPDATE DEPT SET NAME = NAMEA WHERE CODE = CODEA;
IF SQL%ROWCOUNT = 0 THEN
INSERT INTO DEPT(CODE,NAME)VALUES(CODEA,NAMEA);
END IF
COMMIT;

と、SELECT文が無くても良いです。
楽観的なんたらについては、「楽観的同時実行制御」で検索してみて下さい。


引用返信 編集キー/
■20600 / inTopicNo.10)  Re[7]: 新規登録と更新を併せたSQL文の書き方
□投稿者/ eternia (20回)-(2008/06/12(Thu) 18:26:24)
書いてる最中にはつねさんに答え書かれてましたがw
PL/SQLの例(3)ってことで。

SQL実行後にSQL%ROWCOUNTに処理された件数が入ります。
それを利用した方法です。

UPDATE DEPT SET NAME=NAMEA WHERE CODE=CODEA;

IF SQL%ROWCOUNT = 0 THEN

  INSERT INTO DEPT (CODE,NAME)VALUES(CODEA,NAMEA);

END IF;

こんな感じでいける…かな?


引用返信 編集キー/
■20604 / inTopicNo.11)  Re[8]: 新規登録と更新を併せたSQL文の書き方
□投稿者/ キキ (11回)-(2008/06/12(Thu) 19:27:15)
はまやさん!
申し訳ありません;;オラクルでやっていると書き込むのを忘れていました!
楽観的同時実行制御も、勉強になりました!

>SELECT文等は、実行した結果の行数が返ってきます。
>最初にSELECT文で SELECT code FROM DEPT WHERE code = 'CODEA' を実行すると
>存在しなかった場合0が返ってきます。 IFはその結果と比較します。
>0だったらINSERT、1以上ならUPDATE。

自分が勘違いしていた条件文をどうやって書いたらいいか、よく理解できました!有難うございます!!


eternia さん!

カーソルを使わないと駄目でしたね…!

>SQL実行後にSQL%ROWCOUNTに処理された件数が入ります。
>それを利用した方法です。

SQL%ROWCOUNTってなんぞ?って状態だったので、とても助かりました!
丁寧に教えて下さった皆さん本当に有難うございました!!感謝感謝です(´ω`*)
解決済み
引用返信 編集キー/
■20614 / inTopicNo.12)  Re[2]: 新規登録と更新を併せたSQL文の書き方
□投稿者/ Jitta (485回)-(2008/06/12(Thu) 22:25:02)
Jitta さんの Web サイト
No20566 (επιστημη さん) に返信
> # ORACLEにはMERGE INTO... てのがあるそうな
>

SQL Server 2008 で入るみたいですね。
http://www.databasejournal.com/features/mssql/article.php/3739131

解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -