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
以下查询在 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