🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Oracle Database

Oracle Databaseは、米オラクルが開発・販売を行うリレーショナルデータベース管理システムです。

JDBC

JDBC(Java DataBase Connectivity)は、Javaとリーレーショナルデータベースに接続させる基本的なAPIです。Java上でSQLステートメントを発行することで、データベースの種類に影響を受ないDB操作を可能とします。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

解決済

1回答

2657閲覧

[JDBC] CONCUR_UPDATABLEなのにselect for updateで更新ができない

neeg

総合スコア68

Oracle Database

Oracle Databaseは、米オラクルが開発・販売を行うリレーショナルデータベース管理システムです。

JDBC

JDBC(Java DataBase Connectivity)は、Javaとリーレーショナルデータベースに接続させる基本的なAPIです。Java上でSQLステートメントを発行することで、データベースの種類に影響を受ないDB操作を可能とします。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

1グッド

1クリップ

投稿2019/12/12 08:11

編集2019/12/12 08:15

jdbcでOracle12.2に繋げています。
以下のSQLがあり、select文自体は問題なく実行できます。
このSQLに対してfor updateを使って、データを更新しようとしています。

sql

1select 2 senshu.id, senshu.record, p.avg_record avgrec, 3 senshu.gtime, senshu.record, taikai.course_length, 4 p.avg_pace avgpace, 5 senshu.pace wpace, senshu.pace_avg wavg_pace, 6 senshu.record_avg wavg_rec, 7 senshu.pace_rate, senshu.record_rate 8from 9 taikai, senshu, course_param p 10where 11 taikai.src_file=senshu.src_file 12 and taikai.place=p.place 13 and taikai.course_kind=p.course_kind 14 and taikai.course_length=p.course_length 15 and taikai.course_cond=p.course_cond 16 and taikai.cond=p.cond 17 and taikai.inout=p.inout 18for update

(3つのテーブルを結合していますが、更新対象はsenshuテーブルだけです。)
これを実行すると、以下のエラーが発生します。

rs.updateDouble("wpace", pace); java.sql.SQLException: 読取り専用の結果セットに対する操作が無効です。: updateDouble

コネクション自体はCONCUR_UPDATABLEですし、実際に同じトランザクションで
他のテーブルは更新できているので、このSQL文の発行によって接続が
ダウングレードしているようです。

selectした直後に、ステートメントからSQLWarningを取ってみました。

SQLWarning w = statment.getWarnings();

すると、以下の警告がありました。

Warning: リクエストした型および/または同時実行レベルで結果セットを 作成できません。: ORA-00918: 列の定義が未確定です。

列には全てテーブル名を記述しているので、定義が未確定な部分は
ないと思います。(そもそもfor updateをつけなければ問題なく実行できる
SQL文です)
調べてみたところ、
「リクエストした型および/または同時実行レベルで結果セットを作成できません」
というのはJDBCのエラーメッセージのようですが、どのような場合にこのように
「更新可能の結果セットが作成できない」というようなことがおこるでしょうか。

心当たりとしては

  • テーブルを複数(この場合は3つ)結合して得られた結果セットを更新ができない?
  • 対象になる行が多すぎる?

などですが、、、、

A-pZ👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Orlofsky

2019/12/12 09:45

CREATE TABLE, データを何件か INSERTで、SQL の UPDATEや現象を再現できるJDBCのコードを質問に追記しては? SELECT文は今の昔の記述方法ではなくJOIN を使った方がバグが少なそうに思えます。
neeg

2019/12/12 09:50

ありがとうございます。仕様でした。
Orlofsky

2019/12/12 10:05

Oracle9i以下でなければ、JOIN を使わない[仕様]が時代遅れです。
guest

回答1

0

自己解決

マニュアルに記述がありました。

更新可能な結果セットを作成するには、次の制限事項を考慮します。 - リスト問合せによって選択できるのは、単一の表のみです。結合操作を含めることはできません。 - リストさらに、挿入するためには、NULL化可能でない列およびデフォルト値が設定されていない列をすべて、問合せによって選択する必要があります。

失礼しました。。。

投稿2019/12/12 08:41

neeg

総合スコア68

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問