Oracle 中缺少右括号错误

Missing right parenthesis error in Oracle

以下查询在 SQL Server 2012 中运行良好。但是当我尝试在 Oracle 上 运行 它时,它给出 ORA-00907:缺少右括号错误。 想不通我在这里做错了什么。

SELECT p1.ACTION_ID,
       STUFF( (SELECT ',  '+EMP_DISPLAY_NAME
               FROM ( SELECT DISTINCT EMP.EMP_DISPLAY_NAME,ACTS.ACTION_ID
                      FROM HS_HR_OB_ACT_ALT_RECIPIENT ALT
                      LEFT JOIN HS_HR_EMPLOYEE EMP
                          ON EMP.EMP_NUMBER=ALT.ACTALT_EMP_NUMBER
                      LEFT JOIN HS_HR_OB_ACTION ACTS
                          ON ACTS.ACTION_ID=ALT.ACTION_ID) p2
               WHERE p2.ACTION_ID = p1.ACTION_ID
               ORDER BY EMP_DISPLAY_NAME
               FOR XML PATH(''), TYPE).value('.', 'varchar(max)')
            ,1,3,'')
       AS NAME
FROM ( SELECT DISTINCT EMP.EMP_DISPLAY_NAME,ACTS.ACTION_ID
       FROM HS_HR_OB_ACT_ALT_RECIPIENT ALT
       LEFT JOIN HS_HR_EMPLOYEE EMP
           ON EMP.EMP_NUMBER=ALT.ACTALT_EMP_NUMBER
       LEFT JOIN HS_HR_OB_ACTION ACTS
           ON ACTS.ACTION_ID=ALT.ACTION_ID) p1
GROUP BY ACTION_ID 

SELECT ', '+EMP_DISPLAY_NAME

这不是有效的 Oracle 语法。您需要使用连接运算符 ||

例如,SELECT EMP_DISPLAY_NAME||' ,'

测试用例-

SQL> SELECT 'Employee ID is '||empno FROM emp;

'EMPLOYEEIDIS'||EMPNO
----------------------------------------------
Employee ID is 7369
Employee ID is 7499
Employee ID is 7521
Employee ID is 7566
Employee ID is 7654
Employee ID is 7698
Employee ID is 7782
Employee ID is 7788
Employee ID is 7839
Employee ID is 7844
Employee ID is 7876
Employee ID is 7900
Employee ID is 7902
Employee ID is 7934

14 rows selected.

SQL>

根据您的查询,我得出了最小的数据结构:

HS_HR_OB_ACTION (action_id number)
HS_HR_EMPLOYEE (EMP_NUMBER number, emp_display_name varchar2(20))
HS_HR_OB_ACT_ALT_RECIPIENT (ACTALT_EMP_NUMBER number, action_id number)

对于此类数据,以下查询适用于 Oracle 10g。对于 Oracle 11,取消注释第二行并注释第三行。请将结果与 SQL 服务器进行比较。

SELECT p1.ACTION_ID,
    -- (select LISTAGG(emp_display_name, ', ') WITHIN GROUP (ORDER BY emp_display_name)
    (SELECT wmsys.wm_concat(EMP_DISPLAY_NAME)
       FROM (
         SELECT DISTINCT EMP.EMP_DISPLAY_NAME,ACTS.ACTION_ID
           FROM HS_HR_OB_ACT_ALT_RECIPIENT ALT
             LEFT JOIN HS_HR_EMPLOYEE EMP ON EMP.EMP_NUMBER=ALT.ACTALT_EMP_NUMBER
             LEFT JOIN HS_HR_OB_ACTION ACTS ON ACTS.ACTION_ID=ALT.ACTION_ID
         ) p2
       WHERE p2.ACTION_ID = p1.ACTION_ID) AS NAME
  FROM ( 
    SELECT DISTINCT EMP.EMP_DISPLAY_NAME,ACTS.ACTION_ID
      FROM HS_HR_OB_ACT_ALT_RECIPIENT ALT
        LEFT JOIN HS_HR_EMPLOYEE EMP ON EMP.EMP_NUMBER=ALT.ACTALT_EMP_NUMBER
        LEFT JOIN HS_HR_OB_ACTION ACTS ON ACTS.ACTION_ID=ALT.ACTION_ID
    ) p1
  GROUP BY ACTION_ID

我认为这个查询可能还很简化,但我一开始不想在原始版本中干涉太多。

SELECT distinct ACTION_ID, wmsys.wm_concat(EMP_DISPLAY_NAME) -- or listagg(...)
  FROM HS_HR_OB_ACT_ALT_RECIPIENT ALT
    LEFT JOIN HS_HR_EMPLOYEE EMP ON EMP.EMP_NUMBER=ALT.ACTALT_EMP_NUMBER
    LEFT JOIN HS_HR_OB_ACTION ACTS ON ACTS.ACTION_ID=ALT.ACTION_ID
  GROUP BY ACTION_ID

我对 Ponder Stibbons 的回答进行了一些修改,因为它们给出了 CLOB 错误。谢谢@Ponder Stibbons。

SELECT p1.ACTION_ID,
    -- (select LISTAGG(emp_display_name, ',') WITHIN GROUP (ORDER BY emp_display_name)
    (SELECT dbms_lob.substr( wmsys.wm_concat(EMP_DISPLAY_NAME), 4000, 1 ) 
       FROM (
         SELECT DISTINCT EMP.EMP_DISPLAY_NAME,ACTS.ACTION_ID
           FROM HS_HR_OB_ACT_ALT_RECIPIENT ALT
             LEFT JOIN HS_HR_EMPLOYEE EMP ON EMP.EMP_NUMBER=ALT.ACTALT_EMP_NUMBER
             LEFT JOIN HS_HR_OB_ACTION ACTS ON ACTS.ACTION_ID=ALT.ACTION_ID
         ) p2
       WHERE p2.ACTION_ID = p1.ACTION_ID) AS NAME
  FROM ( 
    SELECT DISTINCT EMP.EMP_DISPLAY_NAME,ACTS.ACTION_ID
      FROM HS_HR_OB_ACT_ALT_RECIPIENT ALT
        LEFT JOIN HS_HR_EMPLOYEE EMP ON EMP.EMP_NUMBER=ALT.ACTALT_EMP_NUMBER
        LEFT JOIN HS_HR_OB_ACTION ACTS ON ACTS.ACTION_ID=ALT.ACTION_ID
    ) p1
  GROUP BY ACTION_ID

这也能正常工作。

  SELECT distinct ACTS.ACTION_ID, dbms_lob.substr( wmsys.wm_concat(EMP_DISPLAY_NAME), 4000, 1 )
  FROM HS_HR_OB_ACT_ALT_RECIPIENT ALT
    LEFT JOIN HS_HR_EMPLOYEE EMP ON EMP.EMP_NUMBER=ALT.ACTALT_EMP_NUMBER
    LEFT JOIN HS_HR_OB_ACTION ACTS ON ACTS.ACTION_ID=ALT.ACTION_ID
  GROUP BY ACTS.ACTION_ID