2015-11-26 53 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; 
相關問題