坚持使用Oracle SQL查询

时间:2018-02-01 11:37:27

标签: sql oracle subquery

我们有一个问题让我在过去一周摸不着头脑。该查询适用于一个数据库,但不适用于另一个数据库(对于文本墙道歉):

WITH dataset AS
         (  SELECT COLLECTION_TIMESTAMP,
                   TARGET_NAME,
                   METRIC_NAME,
                   KEY_VALUE,
                   KEY_VALUE2,
                   KEY_VALUE3,
                   COLUMN_LABEL,
                   MAX(VALUE) AS VALUE
              FROM (SELECT TO_CHAR(COLLECTION_TIMESTAMP, 'DD-MM-YYYY HH24:MI:SS') AS COLLECTION_TIMESTAMP,
                           TARGET_NAME,
                           METRIC_NAME,
                           KEY_VALUE,
                           KEY_VALUE2,
                           KEY_VALUE3,
                           COLUMN_LABEL,
                           VALUE
                      FROM (SELECT MAX(COLLECTION_TIMESTAMP)
                                       OVER(
                                            PARTITION BY TARGET_NAME,
                                                         METRIC_NAME,
                                                         KEY_VALUE,
                                                         KEY_VALUE2,
                                                         KEY_VALUE3,
                                                         COLUMN_LABEL
                                           )
                                       max_my_date,
                                   COLLECTION_TIMESTAMP,
                                   TARGET_NAME,
                                   METRIC_NAME,
                                   KEY_VALUE,
                                   KEY_VALUE2,
                                   KEY_VALUE3,
                                   COLUMN_LABEL,
                                   VALUE
                              FROM MGMT$METRIC_DETAILS
                             WHERE METRIC_LABEL LIKE 'SOX%')
                     WHERE COLLECTION_TIMESTAMP = max_my_date)
             WHERE METRIC_NAME = 'ME$SOXREP_USERS'
          GROUP BY COLLECTION_TIMESTAMP,
                   TARGET_NAME,
                   METRIC_NAME,
                   KEY_VALUE,
                   kEY_VALUE2,
                   KEY_VALUE3,
                   COLUMN_LABEL
          ORDER BY TARGET_NAME ASC,
                   METRIC_NAME ASC,
                   COLUMN_LABEL ASC)
  SELECT (SELECT NVL(amt.AGENT_HOST_NAME, ' ') AS AGENT_HOST_NAME
            FROM MGMT$TARGET t LEFT OUTER JOIN MGMT$AGENTS_MONITORING_TARGETS amt ON t.TARGET_GUID = amt.TARGET_GUID
           WHERE t.TARGET_NAME = prf.TARGET_NAME)
             AS "HOSTNAME",
         (SELECT NVL(PROPERTY_VALUE, ' ')
            FROM MGMT$TARGET_PROPERTIES
           WHERE     PROPERTY_NAME = 'IP_address'
                 AND TARGET_NAME = (SELECT NVL(amt.AGENT_HOST_NAME, ' ') AS AGENT_HOST_NAME
                                      FROM MGMT$TARGET t LEFT OUTER JOIN MGMT$AGENTS_MONITORING_TARGETS amt ON t.TARGET_GUID = amt.TARGET_GUID
                                     WHERE t.TARGET_NAME = prf.TARGET_NAME))
             AS "IP ADDRESS",
         (SELECT NVL(PROPERTY_VALUE, ' ')
            FROM MGMT$TARGET_PROPERTIES
           WHERE     PROPERTY_NAME = 'DBVersion'
                 AND TARGET_NAME = prf.TARGET_NAME)
             AS "DB VERSION",
         (SELECT NVL(PROPERTY_VALUE, ' ')
            FROM MGMT$TARGET_PROPERTIES
           WHERE     PROPERTY_NAME = 'InstanceName'
                 AND TARGET_NAME = prf.TARGET_NAME)
             AS "DB INSTANCE",
         'All database accounts' AS DESCRIPTION,
         prf.KEY_VALUE AS "USERNAME",
         prf.VALUE AS "PROFILE",
         acc.VALUE AS "ACCOUNT STATUS",
         CAST(TO_TIMESTAMP(created.VALUE, 'YYYY-MM-DD HH24:MI:SS.FF1') AS DATE) AS "CREATED",
         CAST(TO_TIMESTAMP(passwd.VALUE, 'YYYY-MM-DD HH24:MI:SS.FF1') AS DATE) AS "LAST_PWD_CHANGED",
         d.VALUE AS "DAYS_SINCE_LAST_PWD_CHANGED",
         (SELECT NVL(PROPERTY_VALUE, ' ')
            FROM MGMT$TARGET_PROPERTIES
           WHERE     PROPERTY_NAME = 'orcl_gtp_contact'
                 AND TARGET_NAME = prf.TARGET_NAME)
             AS "ENVIRONMENT ROLES",
         CAST(TO_TIMESTAMP(dl.VALUE, 'YYYY-MM-DD HH24:MI:SS.FF1') AS DATE) AS "LAST LOGON",
         TO_DATE(prf.COLLECTION_TIMESTAMP, 'DD-MM-YYYY HH24:MI:SS') AS "COLLECTION DATE"
    FROM dataset prf,
         dataset acc,
         dataset created,
         dataset passwd,
         dataset d,
         dataset dl
   WHERE     prf.TARGET_NAME = acc.TARGET_NAME
         AND prf.KEY_VALUE = acc.KEY_VALUE
         AND prf.TARGET_NAME = created.TARGET_NAME
         AND prf.KEY_VALUE = created.KEY_VALUE
         AND prf.TARGET_NAME = passwd.TARGET_NAME
         AND prf.KEY_VALUE = passwd.KEY_VALUE
         AND prf.TARGET_NAME = d.TARGET_NAME
         AND prf.KEY_VALUE = d.KEY_VALUE
         AND prf.TARGET_NAME = dl.TARGET_NAME
         AND prf.KEY_VALUE = dl.KEY_VALUE
         AND prf.COLUMN_LABEL = 'PROFILE'
         AND acc.COLUMN_LABEL = 'ACCOUNT STATUS'
         AND created.COLUMN_LABEL = 'CREATED'
         AND passwd.COLUMN_LABEL = 'LAST PWD CHANGE'
         AND d.COLUMN_LABEL = 'Days since last pwd change'
         AND dl.COLUMN_LABEL = 'LAST LOGON'
ORDER BY 1 ASC,
         4,
         5 DESC

在一个数据库上,查询运行正常。但是在另一个数据库中,我们得到以下结果:

  

ORA-01427:单行子查询返回多行   01427. 00000 - “单行子查询返回多行”   *原因:
  *操作:

我一直试图解构查询,试图弄清楚查询的哪一部分导致问题,但到目前为止我没有运气。我知道应该只返回一行的子查询返回2或更多,但我很难弄清楚它是哪一个。

我的问题:有没有更简单的方法让我弄清楚SQL查询的哪个部分导致了问题,而不必尝试解构查询并一点一点地运行它?

1 个答案:

答案 0 :(得分:1)

您可以打包子查询以检查哪个子查询提供了多行,至少对于您不需要检查值的查询。例如:

SQL> select
  2      (select 1 from dual) as result_1,
  3      (select 1 from dual connect by level < 10) as result_2
  4  from dual;
    (select 1 from dual connect by level < 10) as result_2
              *
ERROR at line 3:
ORA-01427: single-row subquery returns more than one row


SQL> select
  2      (select count(1) from (select 1 from dual)) as check1,
  3      (select count(1) from (select 1 from dual connect by level < 10)) as check_2
  4  from dual;

    CHECK1    CHECK_2
---------- ----------
         1          9

您知道问题出在第二个查询中。