12
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

PL/SQLプロシージャで ORA-01861 で詰んだ件

Posted at

今まで動いていたPL/SQLプロシージャが
ある日突然動かなくなりました。

ORA-01861 : literal does not match format string (リテラルが書式文字列と一致しません。)

3つの問題が同時に起きていたのを切り分けできず
相当な時間を浪費してしまったケースをご紹介。

#答えから先に言うと、

  • 日付のformatが異なっていると発生するOracleエラー
  • nls_parametersのdate_langが勝手に書き換えられていた
  • プロシージャの入力がDATE型で、入力に至る前に暗黙的なVARCHAR→DATEをやってた

という3つの問題が同時発生していました。

##いろんな書き方をするよねみんな

日付を文字列で表現するときは、
人によっていろんな書き方をします。

例えば「2017年1月12日」なら

'17-01-12' --'RR-MM-DD'

だの

'12-JAN-17' --'DD-MMM-RR'

だの

'20170112' --'YYYYMMDD'

だの

人によってかなり好き勝手に表現します。

これの指定が間違っている時に
ORA-01861
が発生します。

#フォーマットを指定して変換する例

TO_DATE('17-01-12','RR-MM-DD')

第二引数を省略した場合は
環境変数的なNLSパラメータに依存します。

#NLSパラメータを確認するSQL

 select * from v$nls_parameters;

プロシージャの処理の前で暗黙的な変換してた件!

create or replace PROCEDURE hoge(
  inputHoge IN OUT VARCHAR2
  inputDate IN OUT DATE
  )

で、ここが一番悩んだのですが、

ORA-エラーを吐いていたのは
プロシージャの入力がDATE型だったので
そこで暗黙的変換をしていたのに気が付かなかったのです。

以下のように変更して回避しました。

create or replace PROCEDURE hoge(
  inputHoge IN OUT VARCHAR2
  inputDateChr IN OUT VARCHAR2
  )

一度文字列型のまま受け取って、
プロシージャの下の方で明示的に変換する処理を追加。

この投稿が誰かのお役に立てば幸いです。

12
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?