スポンサーサイト


上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

インラインビューを使ったUPDATE文で"ORA-01779: キー保存されていない表にマップする列は変更できません"のエラーが出る場合の対処法


ORA-01779の回避方法

インラインビューを使ったUPDATE文を実行しようとして

SQL実行中に以下のエラーが発生しました。
ORA-01779: キー保存されていない表にマップする列は変更できません

のエラーが表示されることがある。

これは、インラインビューを使った更新処理において、
更新対象の項目が複数回にわたって更新される可能性がある場合に表示される。
簡単な例だと、ヘッダ-明細形式のテーブル構成を持つ複数のテーブルを結合してインラインビューでUPDATE文を記述した場合に、
ヘッダ側のテーブルのカラムをSET文に含めるとこのエラーが表示されるようだ。

なるほど最もな理由だが、これを回避するのは比較的簡単。
インラインビューのSELECT句に

/*+ BYPASS_UJVC */

を含めるだけで良い。
SELECT句の先頭に、前後に半角スペース等を空けて記載すればOK。
後ろのカンマは不要。

Oracle:Update時に、ORA-01779: キー保存されていない表にマップする列は変更できません のエラーが発生

これでORA-01779のエラーは回避できるようになるが、
更新対象が複数行にわたる場合はその行数分更新処理が行われることになるため、
SET句の記述方法によっては注意が必要なケースがあるかもしれない。
SET句が固定地である場合は単純に上書かれるだけなので、
大きな問題にはならないだろう。

補足1:オプティマイザ・ヒント

ちなみに、この

/*+ XXXXXXXXXX */

という記法は、Oracelのオプティマイザ・ヒントと呼ばれるもので、
使用するインデックスを明示的に指定したり、
FROM句のテーブルの結合順を指定したりできる。

SQLチューニングの必須知識を総ざらい(後編)(3/3) - @IT

補足2:"UJVC"について

さらにちなみに、「BYPASS_UJVC」の「UJVC」は、「Updatable Join View Check」の略。
インラインビューが条件付きで更新可能な場合、常に上書きで更新してくださいねってことだろうか。

まったり開発日誌 BYPASS_UJVC(Updatable Join View Check)
スポンサーサイト

インラインビューを使ったUPDATE文


SQLのUPDATE文は、単一テーブルに対するカラム更新というのが基本だが、
以下のように更新対象がビューであっても条件付きで更新可能になる。

UPDATE [VIEW_NAME] SET [COLUMN_NAME] = [VALUE]
※ [VIEW_NAME]の部分は、SELECT文でも可。

ただし、対象VIEWおよびSELECT文には集合関数やDISTINCT句等を含んでいてはならないという条件があったりする。

UPDATE - オラクル・Oracle SQL 入門
VIEW - オラクル・Oracleをマスターするための基本と仕組み

(あんまりよくないんだけど、)インラインビューは運用保守をやっていてデータパッチをするときに威力を発揮する。
SELECT文でデータを探したり検証したりして、いざデータパッチを行うときには
そのままインラインビューとしてUPDATE文を書いてしまえる。


テーブルを別テーブルの項目で更新する


SQLUPDATE文で、あるテーブルの項目を
別テーブルの項目で更新するには、以下のようにする(Oracleの場合):
UPDATE TABLE_A A
SET column_1 = (SELECT column_2 FROM TABLE_B B
WHERE A.key_column = B.key_column)

ちなみにAccessでは、以下のように書いてもOKのようだ。
UPDATE TABLE_A A, TABLE_B B
SET A.column_1 = B.column_2
WHERE A.key_column = B.key_column

SQL For Practitioners


SQLの特殊文字をエスケープする


SQLのLIKE検索で'%'(パーセント)とか'_'(アンダースコア)がワイルドカードとして使えるが、
'%'や'_'の文字自体を検索したいときにはエスケープしておく必要がある。

例えば、'TEST%'に前方一致するものを検索する時に
'\'をエスケープ文字として使用する場合、以下のような感じになる:

SELECT * FROM ..... WHERE ..... LIKE 'TEST\%%' ESCAPE '\'

SQL PlusのESCAPEシステム変数の設定や、PL/SQLにおけるエスケープ文字とは異なる。


◆ 関連リンク(いずれもSHIFT the Oracle):
実用的な SELECT の使用例
ESCAPE システム変数
PL/SQL のエスケープ文字


SQLのORDER BYのちょっとしたテクニック


テクニックというか、どちらかというと裏技に近く、
本来ならプログラムで対応したほうがよさそうなものだったが、
使う機会があったので一応メモしておく…。

「あるテーブルの項目Aと項目Bが等しいレコードを先頭に持ってきて、
残りは項目Cでソートしたい」というようなケースで、以下のようなSQLを記述した:

SELECT .....
FROM .....
WHERE .....
ORDER BY DECODE(A, B, '0', '1') || C


項目Cの先頭に、A = Bのときは固定文字'0'、A = Bでないときは固定文字'1'を付加することで、
A = Bのレコードが先頭に来るようにしている。

DBにはOracleを使っているのでDECODE文を使用したが、他のRDBMSでも同様にできると思う。


Adsense
ブログ内検索
カテゴリー
最近の記事
カレンダー
09 | 2017/10 | 11
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31 - - - -
月別アーカイブ
feedmeter & あわせて読みたい
フィードメーター - あるシステム屋によるJava開発の記録
あわせて読みたいブログパーツ
プロフィール

kamii

Author:kamii
ピタゴラスイッチ好きなシステム開発屋@二児の父です。

メールフォーム

名前:
メール:
件名:
本文:

カウンター
checker
ページランク


ブログチャート
現在時刻
全エントリ表示

全てのエントリを表示する

RSSフィード
リンク
ブロとも申請フォーム

この人とブロともになる

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。