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

Oracleのsysdateと比較した場合の日付型列の問題のwhere句の使用

    さて、私はそれを複製することができます、そしてそのような振る舞いの背後にある理由は、Oracleの述語の解釈です。

    これを再現できるOSとOracleのバージョン:

    SQL> host ver
    
    Microsoft Windows [Version 6.1.7601]
    
    SQL> select * from v$version;
    
    BANNER
    --------------------------------------------------------------------------------
    Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
    PL/SQL Release 11.2.0.1.0 - Production
    CORE    11.2.0.1.0      Production
    TNS for 64-bit Windows: Version 11.2.0.1.0 - Production
    NLSRTL Version 11.2.0.1.0 - Production
    
    SQL>
    

    最初のケースでは、述語はfilter("D"."DT" IS NOT NULL)に変更されます。 2番目のクエリでは、述語は提供されたとおりに機能しますfilter("D"."DT"<TO_DATE(' 2013-01-20 00:00:00', 'syyyy-mm-dd hh24:mi:ss') OR "D"."DT">[email protected]!)

    SQL> select count(*)
      2  from aaa d
      3  where (d.dt > sysdate)
      4  or d.dt < to_date('20130120','yyyymmdd')
      5  /
    
      COUNT(*)
    ----------
            15
    
    Execution Plan
    ----------------------------------------------------------
    Plan hash value: 977873394
    
    ---------------------------------------------------------------------------
    | Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
    ---------------------------------------------------------------------------
    |   0 | SELECT STATEMENT   |      |     1 |     9 |     3   (0)| 00:00:01 |
    |   1 |  SORT AGGREGATE    |      |     1 |     9 |            |          |
    |*  2 |   TABLE ACCESS FULL| AAA  |    15 |   135 |     3   (0)| 00:00:01 |
    ---------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       2 - filter("D"."DT" IS NOT NULL)
    
    Note
    -----
       - dynamic sampling used for this statement (level=2)
    
    
    Statistics
    
    ----------------------------------------------------------
          4  recursive calls
          0  db block gets
         15  consistent gets
          0  physical reads
          0  redo size
        346  bytes sent via SQL*Net to client
        364  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed
    
    SQL> ed
    Wrote file afiedt.buf
    
      1  select count(*)
      2  from aaa d
      3  where d.dt < to_date('20130120','yyyymmdd')
      4* or (d.dt > sysdate)
    SQL> 
    /
    
      COUNT(*)
    ----------
             7
    
    Execution Plan
    ----------------------------------------------------------
    Plan hash value: 977873394
    
    ---------------------------------------------------------------------------
    | Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
    ---------------------------------------------------------------------------
    |   0 | SELECT STATEMENT   |      |     1 |     9 |     3   (0)| 00:00:01 |
    |   1 |  SORT AGGREGATE    |      |     1 |     9 |            |          |
    |*  2 |   TABLE ACCESS FULL| AAA  |     7 |    63 |     3   (0)| 00:00:01 |
    ---------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       2 - filter("D"."DT"<TO_DATE(' 2013-01-20 00:00:00', 'syyyy-mm-dd
                  hh24:mi:ss') OR "D"."DT">[email protected]!)
    
    Note
    -----
       - dynamic sampling used for this statement (level=2)
    
    Statistics
    
    ----------------------------------------------------------
          4  recursive calls
          0  db block gets
         15  consistent gets
          0  physical reads
          0  redo size
        346  bytes sent via SQL*Net to client
        364  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed
    
    SQL>
    

    Oracleのこの動作を理解できませんでした。一部の専門家がこれを説明できる可能性があります。

    再び3番目の例では、述語が正しく使用されています。 filter("D"."DT"<TO_DATE(' 2013-01-20 00:00:00', 'syyyy-mm-dd hh24:mi:ss') OR INTERNAL_FUNCTION("D"."DT")+1>[email protected]!+1)

    SQL> ed
    Wrote file afiedt.buf
    
      1  select count(*)
      2  from aaa d
      3  where (d.dt + 1 > sysdate + 1)
      4* or d.dt < to_date('20130120','yyyymmdd')
    SQL> /
    
      COUNT(*)
    ----------
             7
    
    Execution Plan
    ----------------------------------------------------------
    Plan hash value: 977873394
    
    ---------------------------------------------------------------------------
    | Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
    ---------------------------------------------------------------------------
    |   0 | SELECT STATEMENT   |      |     1 |     9 |     3   (0)| 00:00:01 |
    |   1 |  SORT AGGREGATE    |      |     1 |     9 |            |          |
    |*  2 |   TABLE ACCESS FULL| AAA  |     7 |    63 |     3   (0)| 00:00:01 |
    ---------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       2 - filter("D"."DT"<TO_DATE(' 2013-01-20 00:00:00', 'syyyy-mm-dd
                  hh24:mi:ss') OR INTERNAL_FUNCTION("D"."DT")+1>[email protected]!+1)
    
    Note
    -----
       - dynamic sampling used for this statement (level=2)
    
    
    Statistics
    ----------------------------------------------------------
              5  recursive calls
              0  db block gets
             15  consistent gets
              0  physical reads
              0  redo size
            346  bytes sent via SQL*Net to client
            364  bytes received via SQL*Net from client
              2  SQL*Net roundtrips to/from client
              0  sorts (memory)
              0  sorts (disk)
              1  rows processed
    
    SQL>
    

    Linuxサーバー上のOracleバージョン11.2.0.2.0および11.2.0.3.0から同じものを再現できないことは明らかです。

    更新:

    Alex Pooleとして コメントで言及-「これはバグ9495697である可能性があります。'同じ列に2つのOR'dフィルタ述語を含むクエリに対して、間違った結果が返される場合があります。一方の述語の反対側はコンパイル時定数ではありません(例:バインド、sysdateなどです。) "




    1. postgresqlダンプをHerokuにインポートする

    2. 行が存在する場合にMySQLテーブルを更新する最速の方法、それ以外の場合は挿入。 2つ以上の一意でないキー

    3. MySQL WorkbenchによってエクスポートされたCREATEスクリプトで、別のコンピューターで構文エラーが発生しました

    4. mysql列の値を含むMulti_Curl