PL / SQL: ошибка неверного номера - PullRequest
0 голосов
/ 23 мая 2018

Я создаю процедуру, для которой я собираю данные, многократно выполняя следующий запрос.

SELECT ATTRIBUTE_VALUE,
       COUNT(src1) CNT1,
       COUNT(src2) CNT2 
FROM   (
  SELECT a.ATTRIBUTE_VALUE,
         1 src1,
         TO_NUMBER(NULL) src2 
  FROM   (
    SELECT DECODE(
             L,
             1, IP_ADDRESS,
             DECODE(
               L,
               2, IP_SUBNET_MASK,
               DECODE(
                 L,
                 3, IP_DEFAULT_GATEWAY
               )
             )
           ) ATTRIBUTE_VALUE 
    FROM   ( SELECT LEVEL L FROM DUAL X CONNECT BY LEVEL <= 3 ), 
           REUT_LOAD_IP_ADDRESSES 
    WHERE  LIP_IPT_NAME = 'CE' 
    AND    IP_LNT_ID IN ( 
             SELECT LNT_ID 
             FROM REUT_LOAD_NTN 
             WHERE LNT_ID IN ( 
               SELECT RLPN.LPN_LNT_ID 
               FROM REUT_LOAD_PI_NTN RLPN 
               WHERE LPN_LPI_ID IN ( 
                 SELECT RLPI.LPI_ID 
                 FROM REUT_LOAD_PAC_INS RLPI 
                 WHERE RLPI.LPI_DATE_ADDED IN ( 
                   SELECT MAX(RLPI2.LPI_DATE_ADDED) 
                   FROM REUT_LOAD_PAC_INS RLPI2 
                   WHERE RLPI2.PI_JOB_ID = P_ORDER_ID 
                 ) 
               ) 
             ) 
             AND IP_CEASE_DATE IS NULL 
             AND LNT_SERVICE_INSTANCE = 'PRIMARY' 
           ) 

Он отлично работает в SQL-разработчике, но при выполнении его в качестве процедуры я получаю INVALID NUMBER ERROR(ORA-01722: неверный номер) на

AND IP_LNT_ID IN ( SELECT LNT_ID, в коде.Могу ли я получить какую-либо помощь?

Ответы [ 2 ]

0 голосов
/ 23 мая 2018

Необходимо убедиться, что:

REUT_LOAD_IP_ADDRESSES.IP_LNT_ID

и

REUT_LOAD_NTN.LNT_ID

имеют одинаковый тип данных или преобразуют / преобразуют один или другой, чтобы они имели одинаковый тип данных.

Существует несколько других проблем:

  1. У вас есть агрегированные и неагрегированные значения:

    SELECT ATTRIBUTE_VALUE,
           COUNT(src1) CNT1,
           COUNT(src2) CNT2 
    FROM   ( ... )
    

    Без предложения GROUP BY.

  2. src2 - это TO_NUMBER(NULL), что составляет всего NULL, а COUNT(NULL) всегда будет 0, поэтому ваш запрос:

    SELECT ATTRIBUTE_VALUE,
           COUNT(src1) CNT1,
           0 CNT2
    ...
    
  3. Этот код:

    SELECT DECODE(
             L,
             1, IP_ADDRESS,
             DECODE(
               L,
               2, IP_SUBNET_MASK,
               DECODE(
                 L,
                 3, IP_DEFAULT_GATEWAY
               )
             )
           ) ATTRIBUTE_VALUE 
    FROM   ( SELECT LEVEL L FROM DUAL X CONNECT BY LEVEL <= 3 ), 
           REUT_LOAD_IP_ADDRESSES 
    

    Может быть переписан как:

    SELECT DECODE(
             L,
             1, IP_ADDRESS,
             2, IP_SUBNET_MASK,
             3, IP_DEFAULT_GATEWAY
           ) ATTRIBUTE_VALUE 
    FROM   ( SELECT LEVEL L FROM DUAL X CONNECT BY LEVEL <= 3 ), 
           REUT_LOAD_IP_ADDRESSES 
    

    Или без объединения как:

    SELECT attribute_value
    FROM   REUT_LOAD_IP_ADDRESSES
    UNPIVOT ( attribute_value FOR L IN (
      IP_ADDRESS         AS 1,
      IP_SUBNET_MASK     AS 2,
      IP_DEFAULT_GATEWAY AS 3
    ) )
    
  4. Самый внутренний запрос:

    SELECT RLPI.LPI_ID 
    FROM REUT_LOAD_PAC_INS RLPI 
    WHERE RLPI.LPI_DATE_ADDED IN ( 
      SELECT MAX(RLPI2.LPI_DATE_ADDED) 
      FROM REUT_LOAD_PAC_INS RLPI2 
      WHERE RLPI2.PI_JOB_ID = P_ORDER_ID 
    ) 
    

    Внутренний запрос ограничен значением RLPI2.PI_JOB_ID = P_ORDER_ID, но нет никакой корреляции между внешним запросом, поэтому вы можете получить результаты, которые не соответствуют P_ORDER_ID, но просто имеютта же дата, что и для соответствующей строки.

0 голосов
/ 23 мая 2018

Ошибка довольно очевидна.Вы сравниваете число с другим типом значения.

Пример:

SELECT 'x'
  FROM DUAL
 WHERE 1 IN (SELECT 'a'
               FROM DUAL)

Это означает, что IP_LNT_ID, LNT_ID, LPN_LNT_ID и LPI_ID должны бытьNUMBERLPI_DATE_ADDED и LPI_DATE_ADDED должны оба быть датой или отметкой времени.

Если это невозможно, вы можете сравнить все как char:

SELECT ATTRIBUTE_VALUE, COUNT(src1) CNT1, COUNT(src2) CNT2 
        FROM (SELECT a.ATTRIBUTE_VALUE, 1 src1, TO_NUMBER(NULL) src2 
            FROM (SELECT 
                    DECODE(L,1,IP_ADDRESS,DECODE(L,2,IP_SUBNET_MASK,DECODE(L,3,IP_DEFAULT_GATEWAY) ) ) ATTRIBUTE_VALUE 
                    FROM 
                    ( 
                        SELECT LEVEL L FROM DUAL X CONNECT BY LEVEL <= 3 
                    ), 
                    REUT_LOAD_IP_ADDRESSES 
                    WHERE LIP_IPT_NAME = 'CE' 
                    AND to_char(IP_LNT_ID) IN ( 
                        SELECT LNT_ID 
                        FROM REUT_LOAD_NTN 
                        WHERE to_char(LNT_ID) IN ( 
                                SELECT RLPN.LPN_LNT_ID 
                                FROM REUT_LOAD_PI_NTN RLPN 
                                WHERE to_char(LPN_LPI_ID) IN ( 
                                    SELECT RLPI.LPI_ID 
                                    FROM REUT_LOAD_PAC_INS RLPI 
                                    WHERE to_char(RLPI.LPI_DATE_ADDED) IN ( 
                                        SELECT MAX(RLPI2.LPI_DATE_ADDED) 
                                        FROM REUT_LOAD_PAC_INS RLPI2 
                                        WHERE RLPI2.PI_JOB_ID = P_ORDER_ID 
                                    ) 
                            ) 
                    ) 
                    AND IP_CEASE_DATE IS NULL 
                    AND LNT_SERVICE_INSTANCE = 'PRIMARY' 
            ) 

Но этого следует избегать прилюбой ценой.К сожалению, иногда нам приходится время от времени обманывать, чтобы работать с существующей инфраструктурой; -)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...