2015-11-26 54 views
0

我想使用公用表表达式和CROSS APPLY在v$sql上运行查询。ORA-00933:使用CROSS APPLY时SQL命令未正确结束

这里是我的SQL:

WITH CTE AS 
    (SELECT 
    SUM(ELAPSED_TIME/1000/1000)/SUM(EXECUTIONS) AS Avg_Elapsed_Time_sec, 
    SUM(ELAPSED_TIME/1000/1000) AS Sum_Elapsed_Time_sec, 
    SUM(ELAPSED_TIME/1000/1000/(executions)) AS Sum_Avg_Elapsed_Time_sec, 
    SUM(EXECUTIONS)      AS Sum_Executions, 
    SUM(ROWS_PROCESSED)     AS Sum_Row_Processed, 
    SUM(ROWS_PROCESSED)/SUM(executions) AS Avg_Row_Processed, 
    SUM(FETCHES)       AS Sum_Fetches, 
    SUM(FETCHES)/SUM(EXECUTIONS)  AS Avg_Fetch, 
    SUM(DISK_READS)      AS Sum_DiskRead, 
    SUM(DISK_READS)/SUM(EXECUTIONS)  AS Avg_DiskRead, 
    SUM(APPLICATION_WAIT_TIME)   AS Sum_Application_Wait_Time, 
    SUM(CONCURRENCY_WAIT_TIME)   AS Sum_Concurrency_Wait_Time, 
    SUM(USER_IO_WAIT_TIME)    AS Sum_User_IO_Wait_Time, 
    SUM(PLSQL_EXEC_TIME)     AS Sum_PlSql_Exec_Time, 
    SUM(OPTIMIZER_COST)     AS Sum_Optimizer_Cost, 
    SQL_ID, 
    HASH_VALUE, 
    COUNT(*)        AS Entries 
    FROM 
    v$sql 
    WHERE 
    executions > 1 
    GROUP BY 
    SQL_ID, 
    HASH_VALUE 
    ORDER BY 
    Avg_Elapsed_Time_sec DESC 
) 
SELECT D.SQL_FULLTEXT,CTE.* FROM v$sql 
CROSS APPLY //Error in this line 
(
    select SQL_FULLTEXT from v$sql where v$sql.SQL_ID=CTE.SQL_ID and rownum=1 
) D 

我怎样才能解决这个问题? 但我得到这个错误:

ORA-00933: SQL command not properly ended 00933. 00000 - "SQL command not properly ended" *Cause:
*Action:

+0

应该使用横向连接。 –

+0

从[这里](https://docs.oracle.com/database/121/SQLRF/statements_10002.htm#BABDADCJ])CROSS APPLY具有JOIN没有的功能 – Kaja

+0

CROSS APPLY的instesd我使用了横向连接,但我得到了另一个错误_ missing keyword_ – Kaja

回答

2

等效将是一个cross join lateral。您还有从CTE中选择的select语句错误。你需要从CTE不从V $ SQL

WITH cte AS 
(
    SELECT .... 
) 
SELECT cte.*, d.sql_fulltext 
FROM cte --<< select from the CTE, not from V$SQL here! 
    CROSS JOIN LATERAL (
     SELECT sql_fulltext 
     FROM v$sql 
     WHERE cte.sql_id = v$sql.sql_id 
     AND rownum = 1 
) d 
ORDER BY Avg_Elapsed_Time_sec DESC; 

选择的order by的CTE没有意义,如果你加入CTE别的东西也不会被保留。您需要将其移至从CTE中选择的语句。

你可以用CROSS APPLYCROSS JOIN LATERAL取代CROSS JOIN LATERAL是标准的SQL,而适用不


编辑针对甲骨文11,你需要使用这样的事情:

WITH cte AS (
    SELECT ... 
) 
SELECT cte.*, 
     d.sql_fulltext 
FROM cte --<< select from the CTE, not from V$SQL here! 
    JOIN (
     SELECT sql_id, 
      sql_fulltext, 
      row_number() over (partition by sql_id order by child_number) as rn 
     FROM v$sql 
) d ON d.sql_id = cte.sql_id and d.rn = 1 
ORDER BY Avg_Elapsed_Time_sec DESC; 

V $ SQL可以为同一个SQL_ID包含多行(针对不同的子游标)。以上语句显示了第一个子游标的SQL文本。

+0

感谢您的回答,但我得到了同样的错误行CROSS JOIN LATERAL – Kaja

+1

@kaja然后你不使用Oracle 12 –

+0

哦,你说得对,我正在使用这个版本:Oracle数据库11g企业版版本11.2.0.1.0 - 64位生产。这个版本有没有解决办法? – Kaja

0

SELECT D.SQL_FULLTEXT,CTE.* FROM v$sql 
CROSS APPLY //Error in this line 
(
    select SQL_FULLTEXT from v$sql where v$sql.SQL_ID=CTE.SQL_ID and rownum=1 
) D 

你不是从CTE中选择(但都直接从时间V $ SQL)。但在交叉应用中引用CTE.SQL_ID。

你可能想从CTE来选择,而不是,所以跨应用会知道你是在谈论:-)

SELECT D.SQL_FULLTEXT,CTE.* FROM CTE 
CROSS APPLY 
(
    select SQL_FULLTEXT from v$sql where v$sql.SQL_ID=CTE.SQL_ID and rownum=1 
) D 

BTW什么:你不需要跨适用于所有:

SELECT 
    (select SQL_FULLTEXT from v$sql where v$sql.SQL_ID = CTE.SQL_ID and rownum = 1), 
    CTE.* 
FROM CTE; 
相关问题