sql >> データベース >  >> RDS >> Oracle

日付値を指定して IN パラメータ プロシージャを実行する場合、有効な月ではありません

    あなたの手続きは timestamp 型のパラメータを取ります .あなたは実際にタイプ varchar2 のパラメータを渡しています あなたの電話で。これにより、Oracle は varchar2 の暗黙的な変換を強制的に実行します。 timestamp へのパラメータ セッションの NLS_TIMESTAMP_FORMAT を使用する .セッションごとに異なる可能性が高いため、文字列がそのセッションの NLS_TIMESTAMP_FORMAT の形式と一致しないため、少なくとも一部のセッションでエラーが発生する可能性があります . to_timestamp を明示的に呼び出して、実際のタイムスタンプを渡したほうがよいでしょう。 またはタイムスタンプ リテラルを渡すことによって。

    次に、プロシージャは timestamp を取ります パラメータを取得し、それらを to_date に渡します 関数。 to_date 関数は timestamp 型のパラメーターを取りません 、タイプ varchar2 のパラメーターのみを取ります .これにより、Oracle は timestamp の別の暗黙的な変換を強制されます。 varchar2 へのパラメータ 、再びセッションの NLS_TIMESTAMP_FORMAT を使用して .セッションの NLS_TIMESTAMP_FORMAT to_date の明示的なフォーマット マスクと一致しません 呼び出すと、エラーが発生するか、予期しない結果が変換によって返されます。

    テーブルの列が実際に date 型である場合 、日付を直接比較できます タイムスタンプに .したがって、to_date を呼び出す理由はないようです。 ここ。ただし、サンプルデータに基づいて、テーブルの列は実際には timestamp 型のようです date ではなく あなたのコードが示すように、 date 以来 小数秒の精度はありません。その場合、 to_date を呼び出すのはさらに意味がありません SELECT で パラメータは実際には timestamp 型であるため、ステートメント 列のタイプは timestamp です . timestamp を比較するだけです

    したがって、私の推測では、次のようなものが必要になると思います

    CREATE OR REPLACE PROCEDURE PROCEDURE PROC1( V_STARTTIME IN TIMESTAMP , V_ENDTIME IN TIMESTAMP )BEGIN INSERT INTO TAB1( <<列名>> ) SELECT COINS FROM TAB2 WHERE <> BETWEEN v_starttime AND v_endtime;END;  

    そして、実際のタイムスタンプを渡してプロシージャを呼び出したいとします。タイムスタンプ リテラルの使用

    proc1(timestamp '2014-05-05 11:25:00', timestamp '2014-05-05 12:25:00' ) を実行  

    または明示的に to_timestamp を呼び出して

    execute proc1( to_timestamp( '5/05/2014 11:25:00 AM', 'MM/DD/YYYY HH:MI:SS AM' ), to_timestamp( '5/05/2014 12:25:00 PM', 'MM/DD/YYYY HH:MI:SS AM' ) );  

    これにより、現在行われているすべての暗黙的な型変換が取り除かれます。




    1. データベースの検索とフィルタリング/リファインはLaravel4になります

    2. MYSQLは同じ行を2回挿入しないようにします

    3. SQLServerINとEXISTSのパフォーマンス

    4. SQLでテーブルを削除する方法