以下のようにするとエラーになってしまいます。
update user set number = (select max(number) from user) + 1 where username = 'myusername';
エラーにならずに実現するにはどうすればよいでしょうか?
SQL分をSELECTとUPDATEの2つにわけては?
トランザクションがあるから、結果は同じになると思われ
るが・・・・。
ORACLEならシーケンスを使ったほうがよさそう。
エラーは 何のエラーが出ますでしょうか?
number という項目名が 予約語で使えないというようなことは ないでしょうか?
回答ありがとうございます。
エラーメッセージは以下のとおりです。
You can't specify target table 'user' for update in FROM clause
お使いのデータベースが何か判りませんが
多くの場合、同じテーブルをサブクエリ内では使えないという制限があります。
一例:MySQL(下記ページ最下段)
MySQL AB :: MySQL 4.1 リファレンスマニュアル :: 6.4.2.9 サブクエリのエラー
VIEWで対応可能になる場合もあるようなのですが
一時テーブルを用いる方法が無難かと思います。
CREATE TEMPORARY TABLE 一時テーブル名 SELECT -中略-;UPDATE -中略-;
MySQL AB :: MySQL 4.1 リファレンスマニュアル :: 6.5.3 CREATE TABLE 構文
気になってしかたないのですが・・・挿入って事はINSERTでは?
まさに、その制限でひっかかってました。
参考になりました。ありがとうございます。
エラーメッセージをしらべて見るとどうも MySQL をお使いのようですね。
そういう時、MySQL では AUTO_INCREMENT を使えばよいようです。
http://dev.mysql.com/doc/refman/4.1/ja/example-auto-increment.ht...
OracleやDB2なら、シーケンスオブジェクトを使います。
蛇足かもしれませんが、サブクエリーを使ってMAX値+1で挿入するやり方は以下の方法で出来ます。(Oracle, DB2)
case を使っているのはレコードが1件もない場合の対処です。また下記のSQLではキーワードで引っかかりそうなカラム名は "" で括っています。
create table "USER" (
"number" integer not null
, username varchar(10) not null
, primary key("number")
);
insert into "USER"("number", username)
values (
(
select
case when max("number") is null then 1 else max("number") + 1 end
from
"USER"
)
, 'myusername'
);
AUTO_INCREMENTも検討したのですが、今回は文字も入っていたので断念しました。
OracleやDB2の例も示していただきありがとうございます。
回答ありがとうございます。
SELECTとUPDATEの2つに分ければ確かにいけそうですね。