查询由于||','||引起的ORA-01791错误

时间:2013-06-13 15:27:52

标签: sql oracle

我收到错误:ORA-01791:当我尝试运行此查询时,不是SELECTed表达式。我可以在SELECT以逗号分隔(AH.NAME,REPLACE(A.ACTIVE_DC,',','/')等)时运行它,但是使用||','||我无法让它发挥作用。如何运行此查询?谢谢!

SELECT DISTINCT
    AH.NAME_1||','||
    REPLACE(A.ACTIVE_DC,',','/')||','||
    REPLACE(A.PASSIVE_DC,',','/')||','||    
    REPLACE(H.ENVIRONMENT,',','/')||','||
    REPLACE(REPLACE(S.NAME,',','-'),'_x','-x')||','||
    H.FULL_NAME||','||
    H.PRIMARY_IP||','||
    H.COMPLIANCE||','||
    H.OS
FROM
    HOST H
FULL OUTER JOIN
    APP_HOST AH ON
        AH.ID_2 = H.ID
FULL OUTER JOIN
    HOST_SVR HS ON
        HS.ID_1 = H.ID
FULL OUTER JOIN 
    APP A ON
        AH.ID_1 = A.ID          
FULL OUTER JOIN
    SVR S ON
        HS.ID_2 = S.ID     
WHERE S.NAME IS NOT NULL     
ORDER BY
    AH.NAME_1,
    REPLACE(REPLACE(S.NAME,',','-'),'_x','-x'),
    H.FULL_NAME

4 个答案:

答案 0 :(得分:4)

由于您没有尝试按顺序排序字段出现在连接中,因此您只能order by 1或重复整个字符串。您可以使用子查询:

SELECT RESULT
FROM (
    SELECT DISTINCT AH.NAME_1,
        REPLACE(REPLACE(S.NAME,',','-'),'_x','-x') AS NAME,
        H.FULL_NAME,
        AH.NAME_1||','||
        REPLACE(A.ACTIVE_DC,',','/')||','||
        REPLACE(A.PASSIVE_DC,',','/')||','||    
        REPLACE(H.ENVIRONMENT,',','/')||','||
        REPLACE(REPLACE(S.NAME,',','-'),'_x','-x')||','||
        H.FULL_NAME||','||
        H.PRIMARY_IP||','||
        H.COMPLIANCE||','||
        H.OS AS RESULT
    FROM
        HOST H
    FULL OUTER JOIN
        APP_HOST AH ON
            AH.ID_2 = H.ID
    FULL OUTER JOIN
        HOST_SVR HS ON
            HS.ID_1 = H.ID
    FULL OUTER JOIN 
        APP A ON
            AH.ID_1 = A.ID          
    FULL OUTER JOIN
        SVR S ON
            HS.ID_2 = S.ID     
    WHERE S.NAME IS NOT NULL     
)
ORDER BY
    NAME_1,
    NAME,
    FULL_NAME

答案 1 :(得分:1)

您需要将复杂的表达式从select部分放到order by部分,或者相反将REPLACE(REPLACE(S.NAME,',','-'),'_x','-x')表达式添加到选择列表中:

SELECT DISTINCT
    AH.NAME||','||
    REPLACE(A.ACTIVE_DC,',','/')||','||
    REPLACE(A.PASSIVE_DC,',','/')||','||    
    REPLACE(H.ENVIRONMENT,',','/')||','||
    REPLACE(REPLACE(S.NAME,',','-'),'_x','-x')||','||
    H.FULL_NAME||','||
    H.PRIMARY_IP||','||
    H.COMPLIANCE||','||
    H.OS
FROM
    HOST H
FULL OUTER JOIN
    APP_HOST AH ON
        AH.ID_2 = H.ID
FULL OUTER JOIN
    HOST_SVR HS ON
        HS.ID_1 = H.ID
FULL OUTER JOIN 
    APP A ON
        AH.ID_1 = A.ID          
FULL OUTER JOIN
    SVR S ON
        HS.ID_2 = S.ID     
WHERE S.NAME IS NOT NULL     
ORDER BY
    -- same as selected
    AH.NAME||','||
    REPLACE(A.ACTIVE_DC,',','/')||','||
    REPLACE(A.PASSIVE_DC,',','/')||','||    
    REPLACE(H.ENVIRONMENT,',','/')||','||
    REPLACE(REPLACE(S.NAME,',','-'),'_x','-x')||','||
    H.FULL_NAME||','||
    H.PRIMARY_IP||','||
    H.COMPLIANCE||','||
    H.OS

上面的查询从任务的角度产生错误的结果,因为排序顺序与初始查询不同。

所以使用第二个选项:

SELECT DISTINCT
    AH.NAME||','||
    REPLACE(A.ACTIVE_DC,',','/')||','||
    REPLACE(A.PASSIVE_DC,',','/')||','||    
    REPLACE(H.ENVIRONMENT,',','/')||','||
    REPLACE(REPLACE(S.NAME,',','-'),'_x','-x')||','||
    H.FULL_NAME||','||
    H.PRIMARY_IP||','||
    H.COMPLIANCE||','||
    H.OS,
    -- next from order by
    AH.NAME_1,
    REPLACE(REPLACE(S.NAME,',','-'),'_x','-x'),
    H.FULL_NAME
FROM
    HOST H
FULL OUTER JOIN
    APP_HOST AH ON
        AH.ID_2 = H.ID
FULL OUTER JOIN
    HOST_SVR HS ON
        HS.ID_1 = H.ID
FULL OUTER JOIN 
    APP A ON
        AH.ID_1 = A.ID          
FULL OUTER JOIN
    SVR S ON
        HS.ID_2 = S.ID     
WHERE S.NAME IS NOT NULL     
ORDER BY
    AH.NAME_1,
    REPLACE(REPLACE(S.NAME,',','-'),'_x','-x'),
    H.FULL_NAME

第二种变体有效,因为所有order by表达式都包含在构造的字符串中,并且不能产生比初始变体更多的不同值。

但是如果你想生成只有一个字段的结果集,那么你必须用子查询分两步完成:第一步不同,第二步 - 排序没有不同:

  select 
    full_string
  from (
    SELECT DISTINCT
        (
          AH.NAME||','||
          REPLACE(A.ACTIVE_DC,',','/')||','||
          REPLACE(A.PASSIVE_DC,',','/')||','||    
          REPLACE(H.ENVIRONMENT,',','/')||','||
          REPLACE(REPLACE(S.NAME,',','-'),'_x','-x')||','||
          H.FULL_NAME||','||
          H.PRIMARY_IP||','||
          H.COMPLIANCE||','||
          H.OS
        ) as full_string,
        -- next from order by
        AH.NAME_1,
        REPLACE(REPLACE(S.NAME,',','-'),'_x','-x') S_NAME_REPLACE,
        H.FULL_NAME,
    FROM
        HOST H
    FULL OUTER JOIN
        APP_HOST AH ON
            AH.ID_2 = H.ID
    FULL OUTER JOIN
        HOST_SVR HS ON
            HS.ID_1 = H.ID
    FULL OUTER JOIN 
        APP A ON
            AH.ID_1 = A.ID          
    FULL OUTER JOIN
        SVR S ON
            HS.ID_2 = S.ID     
    WHERE S.NAME IS NOT NULL     
  )
  ORDER BY
      NAME_1,
      S_NAME_REPLACE,
      FULL_NAME

它起作用,因为在最终查询中没有聚合表达式。

可以在this SQLFiddle找到相关插图。

答案 2 :(得分:0)

我会尝试在内联视图(子查询)中执行distinct,join和order by,并让concatanation在master查询中发生。

答案 3 :(得分:0)

如果没有字符串连接,您的查询将选择多个列,这些列将显示在order by子句中。

使用连接,您只“选择”一列,并且您正在使用不同的列。您只能按照选择不同的列进行排序!这样做的原因是当你执行select distinct时,你可能会“合并”一堆行,这些行的顺序可能实际上是不同的。

编辑:这就是错误的原因,无论如何;我看到其他人已经回答了你如何让它运行的问题。