0

次のコードを見つけました。

select max(id) from TABLE_NAME ...

... do some stuff ...

insert into TABLE_NAME (id, ... )
VALUES (max(id) + 1, ...)

PK のシーケンスを作成できますが、それを使用しない既存のコード (クラシック asp、このプロジェクトの一部ではない既存の asp.net アプリ) がたくさんあります。

私はそれを無視するべきですか、それとも既存のコードに入らずに修正する方法はありますか?

私は最善の選択肢はただ行うことだと考えています:

insert into TABLE_NAME (id, ... )
VALUES (select max(id) + 1, ...)

オプション?

4

6 に答える 6

1

前挿入行トリガーでシーケンスを使用します。select max(id) + 1 は、複数の同時実行環境では機能しません。

于 2009-02-19T19:16:20.973 に答える
1

これはすぐに、アプリケーション アーキテクチャの議論に変わります。特に、質問が「どうすればよいか」に要約される場合は特にそうです。

Oracleの主キーは実際にはシーケンスから取得する必要があり、アプリケーションコードで複雑な挿入ロジック(少なくとも親/子挿入)を扱っているため、既存のコードに入る必要があります(トリガーがおそらく勝ったため)あなたを助けません)。

極端な例として、アプリケーションから SQL への直接アクセスを取り除き、サービスを呼び出すようにして、挿入/更新/削除コードを集中化することができます。または、ある種の MVC アーキテクチャを使用してコードを書き直すこともできます。どちらもあなたの状況ではやり過ぎだと思います。

id 列は少なくとも真の主キーに設定されているので、重複が発生しないようにする制約がありますか? そうでない場合は、そこから始めてください。

主キーが配置されたら、または既に配置されている場合は、挿入が失敗し始めるのは時間の問題です。彼らがいつ失敗し始めるかがわかりますよね?そうでない場合は、エラーログを取得します。

次に、アプリケーション コードを修正します。そこにいる間は、少なくともヘルパー コードを作成して呼び出す必要があります。これにより、データベースとのやり取りが可能な限り少ない場所で行われます。次に、他の開発者にリーダーシップを発揮し、ヘルパー コードも使用するようにします。

于 2009-02-19T22:40:50.260 に答える
0

これは、変数の最大値をフェッチして、次のようにテーブルに挿入することで実行できます。

v_maxintを宣言します。テーブルからv_maxにmax(id)を選択します。

テーブルに挿入values((v_max + rownum)、val1、val2 ....、valn); 専念;

これにより、一括挿入だけでなく単一挿入でもシーケンスが作成されます。

于 2013-02-18T09:12:57.733 に答える
0

大きな質問:PKの値に依存している人はいますか?そうでない場合は、トリガーを使用して、シーケンスからIDをフェッチし、設定することをお勧めします。インサートはIDをまったく指定しませんでした。

よくわかりませんが

TABLE_NAME(id、...)VALUES(select max(id)+ 1、...)に挿入します

セッションがそのコードに到達すると、問題が発生する可能性があります。オラクルがテーブルを読み取り(max(id)を計算)、挿入のためにPKのロックを取得しようとしている可能性があります。その場合、2つの同時セッションが同じIDを使用しようとし、2番目のセッションで例外が発生する可能性があります。

トリガーにログを追加して、IDがすでに設定されている挿入が処理されるかどうかを確認できます。したがって、古いコードが使用されている場所をまだ探す必要があることを知っています。

于 2009-02-19T15:32:25.877 に答える