缺少GROUP BY表示式可以順利執行的問題(二)
Oracle9204上執行一個明顯語法錯誤的SQL,卻可以得到查詢結果。
網友gclizh指出,使用MERGE提示可以在10g中避免錯誤的發生而得到執行結果。根據這個結果進一步分析問題。
缺少GROUP BY表示式可以順利執行的問題:http://yangtingkun.itpub.net/post/468/451079
使用提示MERGE,可以在10g中重現這個問題。說明這個問題的引入是由於Oracle將內層子查詢進行MERGE操作,把GROUP BY操作放在了最後。
10G中使用MERGE提示可以重現這個問題:
SQL> CONN YANGTK/YANGTK@YTK102
已連線。
SQL> SELECT * FROM V$VERSION;
BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod
PL/SQL Release 10.2.0.1.0 - Production
CORE 10.2.0.1.0 Production
TNS for 32-bit Windows: Version 10.2.0.1.0 - Production
NLSRTL Version 10.2.0.1.0 - Production
SQL> CREATE TABLE T1 AS SELECT * FROM DBA_OBJECTS;
表已建立。
SQL> CREATE TABLE T2 AS SELECT * FROM DBA_USERS;
表已建立。
SQL> SELECT USERNAME, OBJECT_TYPE, CN
2 FROM (SELECT OWNER, OBJECT_TYPE, COUNT(*) CN FROM T1 GROUP BY OBJECT_TYPE), T2
3 WHERE USERNAME = OWNER
4 AND USERNAME LIKE 'SYS%';
FROM (SELECT OWNER, OBJECT_TYPE, COUNT(*) CN FROM T1 GROUP BY OBJECT_TYPE), T2
*
第 2 行出現錯誤:
ORA-00979: 不是 GROUP BY 表示式
SQL> SET AUTOT ON EXP
SQL> SELECT /*+ MERGE(T) */ USERNAME, OBJECT_TYPE, CN
2 FROM (SELECT OWNER, OBJECT_TYPE, COUNT(*) CN FROM T1 GROUP BY OBJECT_TYPE) T, T2
3 WHERE USERNAME = OWNER
4 AND USERNAME LIKE 'SYS%';
USERNAME OBJECT_TYPE CN
------------------------------ ------------------- ----------
SYS PACKAGE BODY 497
SYSTEM VIEW 12
SYS LIBRARY 111
SYS RULE SET 11
SYSTEM INDEX PARTITION 32
.
.
.
SYS SCHEDULE 1
SYS JOB 4
SYSMAN TYPE 212
SYSMAN PROCEDURE 2
已選擇66行。
執行計劃
----------------------------------------------------------
Plan hash value: 51733071
----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 6813 | 379K| 167 (4)| 00:00:03 |
| 1 | HASH GROUP BY | | 6813 | 379K| 167 (4)| 00:00:03 |
|* 2 | HASH JOIN | | 6813 | 379K| 165 (3)| 00:00:02 |
|* 3 | TABLE ACCESS FULL| T2 | 3 | 87 | 3 (0)| 00:00:01 |
|* 4 | TABLE ACCESS FULL| T1 | 22710 | 620K| 162 (3)| 00:00:02 |
----------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("USERNAME"="OWNER")
3 - filter("USERNAME" LIKE 'SYS%')
4 - filter("OWNER" LIKE 'SYS%')
Note
-----
- dynamic sampling used for this statement
從執行計劃上看,確實這是造成問題的真正原因。而且在9i中,如果使用NO_MERGE的提示也確實可以避免這個問題:
SQL> SELECT * FROM V$VERSION;
BANNER
----------------------------------------------------------------
Oracle9i Enterprise Edition Release 9.2.0.4.0 - Production
PL/SQL Release 9.2.0.4.0 - Production
CORE 9.2.0.3.0 Production
TNS for 32-bit Windows: Version 9.2.0.4.0 - Production
NLSRTL Version 9.2.0.4.0 - Production
SQL> CREATE TABLE T1 AS SELECT * FROM DBA_OBJECTS;
表已建立。
SQL> CREATE TABLE T2 AS SELECT * FROM DBA_USERS;
表已建立。
SQL> SET AUTOT ON EXP
SQL> SELECT USERNAME, OBJECT_TYPE, CN
2 FROM (SELECT OWNER, OBJECT_TYPE, COUNT(*) CN FROM T1 GROUP BY OBJECT_TYPE), T2
3 WHERE USERNAME = OWNER
4 AND USERNAME LIKE 'SYS%';
USERNAME OBJECT_TYPE CN
------------------------------ ------------------ ----------
SYS LOB 31
SYS TYPE 644
SYS VIEW 2090
SYS INDEX 315
SYS QUEUE 4
SYS TABLE 347
.
.
.
SYSTEM PACKAGE BODY 1
SYSTEM INDEX PARTITION 24
SYSTEM TABLE PARTITION 27
已選擇40行。
執行計劃
----------------------------------------------------------
0 SELECT STATEMENT ptimizer=CHOOSE
1 0 SORT (GROUP BY)
2 1 MERGE JOIN
3 2 SORT (JOIN)
4 3 TABLE ACCESS (FULL) OF 'T2'
5 2 SORT (JOIN)
6 5 TABLE ACCESS (FULL) OF 'T1'
SQL> SELECT /*+ NO_MERGE(T) */ USERNAME, OBJECT_TYPE, CN
2 FROM (SELECT OWNER, OBJECT_TYPE, COUNT(*) CN FROM T1 GROUP BY OBJECT_TYPE) T, T2
3 WHERE USERNAME = OWNER
4 AND USERNAME LIKE 'SYS%';
FROM (SELECT OWNER, OBJECT_TYPE, COUNT(*) CN FROM T1 GROUP BY OBJECT_TYPE) T, T2
*
第 2 行出現錯誤:
ORA-00979: 不是 GROUP BY 表示式
對於Oracle來說,先執行關聯操作,然後對關聯的結果執行GROUP BY操作是可以得到正確的答案的,但是對於這種寫法顯然是有問題的。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/4227/viewspace-149071/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 缺少GROUP BY表示式可以順利執行的問題
- GROUPBY 和開窗函式執行順序的問題函式
- mysql order by 和 group by 順序問題MySql
- sql中的or與and的執行順序問題SQL
- 關於defer執行順序問題
- SQL語句中的AND和OR執行順序問題SQL
- ajax回撥函式執行順序帶來的同步非同步問題函式非同步
- SQL中rownum和order by的執行順序的問題SQL
- C++輸出流cout的執行順序問題C++
- 【Oracle】where條件執行順序(上篇的問題延伸)Oracle
- java正規表示式之 groupJava
- connect by與where條件執行順序問題
- 1.自執行函式表示式函式
- js解惑-函式執行順序JS函式
- 南大通用GBase 8s_GROUP BY支援標量函式和表示式問題詳解函式
- await會阻塞其所在表示式中後續表示式的執行AI
- JS中使用EL表示式的問題JS
- Java公式:如何執行字串表示式?!Java公式字串
- js 立即執行函式表示式介紹JS函式
- 讓quake3在linux下順利執行(轉)Linux
- js基礎進階–promise和setTimeout執行順序的問題JSPromise
- group by 排序問題排序
- 多個執行緒順序列印問題,一網打盡執行緒
- unittest.TestCase中測試用例執行順序問題
- Lcust 分散式執行時的引數化問題分散式
- PG 中表示式的計算順序
- IIFE (Imdiately Invoked Function Expression 立即執行的函式表示式)FunctionExpress函式
- 執行JPetStore的問題
- crontab的執行問題
- JavaScript 立即執行函式表示式 ( IIFE ) 用例JavaScript函式
- 詳解javascript立即執行函式表示式(IIFE)JavaScript函式
- 【odoo】【知識點】生成pdf檔案時缺少樣式的問題Odoo
- function.procedure函式下的過程執行問題Function函式
- 關於執行緒插入函式如何用的問題執行緒函式
- JavaScript的執行順序JavaScript
- [BUG反饋]public function group() 方法缺少網頁標題賦值Function網頁賦值
- Python執行緒專題10:queue、多執行緒按順序執行Python執行緒
- 關於觸發器在行級和語句級的執行順序問題觸發器