DBAsupport.com Forums - Powered by vBulletin
Results 1 to 3 of 3

Thread: Ora-22818

  1. #1
    Join Date
    Nov 2007
    Posts
    1

    Ora-22818

    Hi All,

    Iam getting an error while using this query-

    ERROR-ORA-22818: subquery expressions not allowed here

    QUERY:

    SELECT ROUND(MONTHS_BETWEEN (
    (SELECT TO_DATE('01-'||period_name,'DD-MON-RRRR') FROM gl_periods GP WHERE
    TRUNC(SYSDATE) BETWEEN TRUNC(GP.START_DATE) AND TRUNC(GP.END_DATE)
    AND GP.PERIOD_SET_NAME = 'AT Calendar'
    AND GP.Period_NUM BETWEEN 1 AND 12
    ),
    (SELECT DISTINCT(TO_DATE('01-'||period_name,'DD-MON-RRRR')) FROM gl_periods GP,INV.MTL_TRANSACTION_ACCOUNTS WHERE
    TRUNC(INV.MTL_TRANSACTION_ACCOUNTS.TRANSACTION_DATE) BETWEEN TRUNC(GP.START_DATE) AND TRUNC(GP.END_DATE)
    AND GP.PERIOD_SET_NAME = 'AT Calendar'
    AND GP.Period_NUM BETWEEN 1 AND 12
    )
    ) )



    FROM DUAL

  2. #2
    Join Date
    Mar 2007
    Location
    Ft. Lauderdale, FL
    Posts
    3,555
    The good news is function supports subquery, please see test query below...
    Code:
    select  round(months_between(
            (select sysdate from dual),
            (select sysdate -60 from dual)
            ))
    from    dual;
    You have to look into your individual subqueries and be sure they return an unique DATE; we cannot do it for you 'cause we do not have your involved tables.

    Hope this helps.
    Pablo (Paul) Berzukov

    Author of Understanding Database Administration available at amazon and other bookstores.

    Disclaimer: Advice is provided to the best of my knowledge but no implicit or explicit warranties are provided. Since the advisor explicitly encourages testing any and all suggestions on a test non-production environment advisor should not held liable or responsible for any actions taken based on the given advice.

  3. #3
    Join Date
    Nov 2000
    Location
    Baltimore, MD USA
    Posts
    1,339
    First, let's clean this up a little and see what you're actually trying to do:
    Code:
    SELECT 
       ROUND(
          MONTHS_BETWEEN (
             (
             SELECT 
                TO_DATE('01-'||PERIOD_NAME,'DD-MON-RRRR') 
             FROM 
                GL_PERIODS GP 
             WHERE
                TRUNC(SYSDATE)       BETWEEN  TRUNC(GP.START_DATE) 
                                     AND      TRUNC(GP.END_DATE)      AND 
                GP.PERIOD_SET_NAME   =        'AT CALENDAR'           AND 
                GP.PERIOD_NUM        BETWEEN   1 
                                     AND      12
             ), 
             (
             SELECT 
                DISTINCT(TO_DATE('01-'||PERIOD_NAME,'DD-MON-RRRR')) 
             FROM 
                GL_PERIODS                     GP,
                INV.MTL_TRANSACTION_ACCOUNTS   MTA
             WHERE
                TRUNC(MTA.TRANSACTION_DATE)   BETWEEN  TRUNC(GP.START_DATE) 
                                              AND      TRUNC(GP.END_DATE)   AND 
                GP.PERIOD_SET_NAME            =        'AT CALENDAR'        AND 
                GP.PERIOD_NUM                 BETWEEN   1 
                                              AND      12
             )
          ) 
       )
    FROM
       DUAL
    This leads me to several questions:

    - If you need a DISTINCT, I'm guessing that multiple records are being returned without the DISTINCT. My guess is that multiple records are being returned even *with* the DISTINCT.

    - Avoid BETWEEN - it leads to doing TRUNC()s, which are bad. Any column modified by a function will not use an index (except function-based indexes), so try not to do it.

    - Why are you using TRUNC() on a GP.START_DATE and GP.END_DATE? Why would these values not already be date-only? There should be triggers that guarantee that these values are date-only so you don't have to TRUNC() them everywhere and screw up your indexes.

    So, IF this query worked, it would be much better to write is as:

    Code:
    SELECT
       ROUND(
          MONTHS_BETWEEN (
             (
             SELECT
                TO_DATE('01-'||PERIOD_NAME,'DD-MON-RRRR')
             FROM
                GL_PERIODS GP
             WHERE
                GP.START_DATE        <=  SYSDATE         AND
                GP.END_DATE          >   SYSDATE - 1     AND
                GP.PERIOD_SET_NAME   =   'AT CALENDAR'   AND
                GP.PERIOD_NUM        >=  1               AND
                GP.PERIOD_NUM        <=  12
             ),
             (
             SELECT
                DISTINCT(TO_DATE('01-'||PERIOD_NAME,'DD-MON-RRRR'))
             FROM
                INV.MTL_TRANSACTION_ACCOUNTS    MTA,
                GL_PERIODS                     GP
             WHERE
                MTA.TRANSACTION_DATE   >=   GP.START_DATE             AND
                   -- Yes, these 'say' the same thing, but it gives the 
                   --   optimizer more choices, which is always good
                MTA.TRANSACTION_DATE   <   GP.END_DATE + 1            AND
                GP.END_DATE            >   MTA.TRANSACTION_DATE   - 1 AND
                GP.PERIOD_SET_NAME     =   'AT CALENDAR'              AND
                GP.PERIOD_NUM          >=   1                         AND
                GP.PERIOD_NUM          <=   12
             )
          )
       )
    FROM
       DUAL
    But you need to be more specific about what you are actually trying to do, because my guess is that the SQL is completely wrong.
    Christopher R. Long
    ChrisRLong@HotMail.Com
    But that's just my opinion. I could be wrong

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Click Here to Expand Forum to Full Width