ORA-00933: 使用 CROSS APPLY 时 SQL 命令未正确结束
Posted
技术标签:
【中文标题】ORA-00933: 使用 CROSS APPLY 时 SQL 命令未正确结束【英文标题】:ORA-00933: SQL command not properly ended while using CROSS APPLY 【发布时间】:2015-11-26 10:13:48 【问题描述】:我想使用公用表表达式和 CROSS APPLY 对 v$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 命令未正确结束 00933. 00000 - “SQL 命令未正确结束” *原因: *行动:
【问题讨论】:
应该使用横向连接。 From hereCROSS APPLY 有 JOIN 没有的功能 Instesd of CROSS APPLY 我使用横向连接,但我得到另一个错误_缺少关键字_ 【参考方案1】:等价的将是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
inside CTE 没有意义,如果您将 CTE 加入其他内容,它将不会被保留。您需要将其移到从 CTE 中选择的语句中。
您可以将CROSS JOIN LATERAL
替换为CROSS APPLY
,但CROSS JOIN LATERAL
是标准SQL 而APPLY 不是
Edit 对于 Oracle 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 文本。
【讨论】:
感谢您的回答,但我在 CROSS JOIN LATERAL 行中遇到了同样的错误 @kaja 那你没有使用 Oracle 12 哦,你是对的,我使用的是这个版本:Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production。这个版本有解决方案吗?【参考方案2】:在
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。
你可能想选择 FROM 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
顺便说一句:您根本不需要 CROSS APPLY:
SELECT
(select SQL_FULLTEXT from v$sql where v$sql.SQL_ID = CTE.SQL_ID and rownum = 1),
CTE.*
FROM CTE;
【讨论】:
以上是关于ORA-00933: 使用 CROSS APPLY 时 SQL 命令未正确结束的主要内容,如果未能解决你的问题,请参考以下文章
ORA-00933: SQL 命令未正确结束 00933. 00000 - “SQL 命令未正确结束
为啥会出现“ORA-00933:SQL 命令未正确结束”错误(立即执行)?
ORA-00933: 运行创建序列命令时 SQL 命令未正确结束