しろあじ備忘録

システム関係の備忘録。ザルのような記憶力なので、こうして書いておかないと忘れるのだよ。

【Oracle】パッケージが削除・リコンパイルできなくなった時の覚書

Oracle でパッケージを変更しコンパイルしたがエラー。
Package Bodyは問題ないが、Package を見ると
「ORA-04043:オブジェクト SYS_PLSQL_12345678_123_1は存在しません。」(数字はダミー)

これが出ると、このPackageはリコンパイルも削除もできなくなる。
そのときの対処備忘録

PIPELINEを返すFunctionリコンパイルでエラー

多分、要因はこれだと思う。

最初にPIPELINEを返すFunction含むパッケージを作成、コンパイルが通った。

その後、仕様変更で、PIPELINEの項目を変更した。

するとコンパイルが通らなくなったのである。

単なる構文ミスかと思いきや、、

f:id:ramapipi:20200521163551p:plain
oracle package error

構文ではないようだ。

TYPE を見ても見つからず

SYS_PLSQL_hogehogeは、以下のTYPEオブジェクトのところにある

f:id:ramapipi:20200521163745p:plain
oracle package error

でも、指定されたTYPEは見つからない。
そうだよな、存在しない、って言っているのだし。

結論:sysdba としてSYSユーザーで原因を削除

ネットで調べまくったが、調べ方が悪いのか、なかなかヒットしない。

でも、簡単に再現できるから、誰かしらはまってるはずなんだ。


そして、下記のサイトにたどり着いた。
stackoverrun.com

質問内容を抜粋すると

ORA-04043:オブジェクトSYS_PLSQL_77721_489_1が存在しません
この後、パッケージを再コンパイルまたは削除できなくなりました。

まさにそれだ。

そして、解決させるなら以下の手順
1)sysdba としてSYSユーザーでSQLPLUSでも開く(このユーザーでログインできるならなんでもよいが)
2)DROP TYPE SYS_PLSQL_12345678_123_1; を実行(数値はエラーメッセージの数値) 
  ⇒ここで削除できましたと出るときと、オブジェクトないよとなったときもあったが気にしないこと。
3)DROP TYPE SYS_PLSQL_12345678_DUMMY_1; を実行(数値はエラーメッセージの数値) 
4)DROP PACKAGE リコンパイルOR削除したいパッケージ名;

これできれいな状態になるので、あらためていつものようにパッケージコンパイルできる。

Oracleのバグらしい。。

でもなんなのか。

先ほどのサイトによると、
「PIPELINEを使用したときに発生するバグ」とのこと。

バグ情報は
www.oracle-developer.net

日本語だと、問題3:バージョン管理されたオブジェクト:ora-04043
にまさにそれについて触れている。
ただ11gで解決したような言い回しなんだよなあ。。。英語なので解読不足もあるかもだが。
ちなみに今回私が扱ったのはOracle12である。うーん。

まあ、とりあえず対処はできるようになったので良しとしよう。

追記:それでもパッケージが削除・リコンパイルできない場合

上記の手段が分かり一件落着かと思いきや
それでも削除・リコンパイルできないときがあった。

そこでObject BrowserでTYPEを見ると、

f:id:ramapipi:20200523102238p:plain
oracle package error

その前にエラーとなっていたTYPEとは異なるTYPEにエラー表示が出ている

それらを右クリックして「再コンパイル」するとあっさりコンパイルできた。

すると、問題のパッケージも削除・リコンパイルできるようになった。

深く追求していないが、直接ではないが何か経由で関係しているTYPEっぽい。

さらに追記:結局この形に落ち着いた。

いろいろとかいてきたが、
問題の箇所を削除してコンパイルの繰り返しで手間がかかる。
しかも、PIPELINEが一部値を返さない、といった現象も時々起きる。

結局、ソースを修正したさいには
そして、私はオブジェクトブラウザ
・関連するタイプ全部削除 SYS_PLSQL_77721_489_1 であれば、 SYS_PLSQL_77721 が付くものすべて消す
・パッケージも削除
・それで最新のソースをコンパイル

の形になった。
問題の箇所を特定してそこだけ直すより、SYS_PLSQL_77721が付くものぜーんぶ消しちゃったほうが手間は減るし時間も少ない

次回はPIPELINEは使わないようにしよう。。。。(個人的な意見です)

f:id:ramapipi:20200521190725p:plain