--列出所有應用模組對應的ID
SELECT
appview.APPLICATION_ID
,appview.APPLICATION_SHORT_NAME
,appview.APPLICATION_NAME
,appview.DESCRIPTION
FROM
fnd_application_all_view appview
WHERE APPLICATION_SHORT_NAME ='ONT'
--列出所有應用模組對應的執行程式名稱,掛上的FORM名稱
SELECT
conpro.CONCURRENT_PROGRAM_ID
,conpro.CONCURRENT_PROGRAM_NAME
,conpro.DESCRIPTION
,conpro.APPLICATION_ID
FROM
FND_CONCURRENT_PROGRAMS_VL conpro
WHERE APPLICATION_ID=660
- 5月 26 週二 200911:46
查詢ORACLE 上傳檔案的內容
- 4月 02 週四 200915:03
CONSTRAINT SQL運用
項目PRIMARY KEY 單一PRIMARY KEY 複合建立CREATE TABLE customer
(
C_Id INT NOT NULL PRIMARY KEY,
Name VARCHAR(50) NOT NULL,
Address VARCHAR(255),
Phone VARCHAR(20)
);
- 3月 17 週二 200916:20
ORACLE SQL 總整理
- 9月 17 週三 200813:57
取SQL substr&instr分割字串欄位語法
- 9月 09 週二 200814:01
SQL 三種JOIN語法的差異
三種JOIN語法的差異
敘述
用途說明
INNER JOIN
僅顯示兩資料表對應欄位中值相同的欄位。
LEFT JOIN
串聯兩個資料表中對應欄資料時,以資料表1的資料為主,若資料存在於資料表1,但資料表2沒有對應值時,仍顯示資料表1中的資料。
RIGHT JOIN
串聯兩個資料表中對應欄資料時,以資料表2的資料為主,若資料存在於資料表2,但資料表1沒有對應值時,仍顯示資料表2中的資料。
- 9月 09 週二 200814:00
SQL 優化語法 (1)
http://www.searchfull.net/blog/2006/11/18/1163822247129.html
http://blog.roodo.com/emisjerry/archives/cat_3885.html
一、TABLE 結構表
fphm,kshm
2014,00000001
2014,00000002
2014,00000003
2014,00000004
2014,00000005
2014,00000007
2014,00000008
2014,00000009
2013,00000120
2013,00000121
2013,00000122
2013,00000124
2013,00000125
怎樣可以得到下列結果
2014,00000001,00000005
2014,00000009,00000007
2013,00000120,00000122
2013,00000124,00000125
解法 :
SQL> SELECT b.fphm, MIN (b.kshm) Start_HM, MAX (b.kshm) End_HM
2 FROM (SELECT a.*, TO_NUMBER (a.kshm - ROWNUM) cc
3 FROM (SELECT *
4 FROM t
5 ORDER BY fphm, kshm) a) b
6 GROUP BY b.fphm, b.cc
7 /
結果
FPHM START_HM END_HM
---------- -------- --------
2013 00000120 00000122
2013 00000124 00000125
2014 00000001 00000005
2014 00000007 00000009
第二種解法
select b.fphm,min(b.kshm),max(b.kshm)
from (
select a.*,to_number(a.kshm-rownum) cc
from (
select * from t order by fphm,kshm
) a
) b
group by b.fphm,b.cc
2.高效與低效
(1)
低效:
SELECT …
FROM DEPT
WHERE SAL * 12 > 25000;
高效:
SELECT …
FROM DEPT
WHERE SAL > 25000/12;
(2)
高效:
SELECT *
FROM EMP
WHERE DEPTNO >=4
低效:
SELECT *
FROM EMP
WHERE DEPTNO >3
(3)
高效:
SELECT LOC_ID , LOC_DESC , REGION
FROM LOCATION
WHERE LOC_ID = 10
UNION
SELECT LOC_ID , LOC_DESC , REGION
FROM LOCATION
WHERE REGION = “MELBOURNE”
低效:
SELECT LOC_ID , LOC_DESC , REGION
FROM LOCATION
WHERE LOC_ID = 10 OR REGION = "MELBOURNE"
(4)
低效: (索引失效)
SELECT …
FROM DEPARTMENT
WHERE DEPT_CODE IS NOT NULL;
高效: (索引有效)
SELECT …
FROM DEPARTMENT
WHERE DEPT_CODE >=0;
不使用索引:
SELECT ACCOUNT_NAME
FROM TRANSACTION
WHERE AMOUNT !=0;
使用索引:
SELECT ACCOUNT_NAME
FROM TRANSACTION
WHERE AMOUNT >0;
(5)
例如:
(低效執行約156.3秒)
SELECT …
FROM EMP E
WHERE SAL > 50000
AND JOB = ‘MANAGER’
AND 25 < (SELECT COUNT(*) FROM EMP
WHERE MGR=E.EMPNO);
(高效,執行約10.6秒)
SELECT …
FROM EMP E
WHERE 25 < (SELECT COUNT(*) FROM EMP
WHERE MGR=E.EMPNO)
AND SAL > 50000
AND JOB = ‘MANAGER’;
(6)
方法3 (高效)
SELECT A.EMP_NAME , A.SALARY , A.GRADE,
B.EMP_NAME , B.SALARY , B.GRADE
FROM EMP A,EMP B
WHERE A.EMP_NO = 342
AND B.EMP_NO = 291;
(7)
使用DECODE函數來減少處理時
使用DECODE函數可以避免重復描述相同記錄或重復連結相同的表
例如:
SELECT COUNT(*),SUM(SAL)
FROM EMP
WHERE DEPT_NO = 0020
AND ENAME LIKE ‘SMITH%’;
SELECT COUNT(*),SUM(SAL)
FROM EMP
WHERE DEPT_NO = 0030
AND ENAME LIKE ‘SMITH%’;
你可以用DECODE函數更高效
SELECT COUNT(DECODE(DEPT_NO,0020,’X’,NULL)) D0020_COUNT,
COUNT(DECODE(DEPT_NO,0030,’X’,NULL)) D0030_COUNT,
SUM(DECODE(DEPT_NO,0020,SAL,NULL)) D0020_SAL,
SUM(DECODE(DEPT_NO,0030,SAL,NULL)) D0030_SAL
FROM EMP WHERE ENAME LIKE ‘SMITH%’;
3.使用日期
當使用日期時,需要注意如果有超過5位小數加到日期上,這個日期會到下一天
例如:
1.
SELECT TO_DATE(‘01-JAN-93’+.99999)
FROM DUAL;
Returns:
’01-JAN-93 23:59:59’
2.
SELECT TO_DATE(‘01-JAN-93’+.999999)
FROM DUAL;
Returns:
’02-JAN-93 00:00:00’
4.以筆數多的放在前面
表 TAB1 16,384 筆
表 TAB2 1 筆
選擇TAB2作為基礎表 (最好的方法)
select count(*) from tab1,tab2 執行約0.96秒
選擇TAB2作為基礎表 (不佳的方法)
select count(*) from tab2,tab1 執行約26.09秒
5.不同表的效能
原表 :
SELECT NAME
FROM EMP
WHERE EMP_NO = 1234;
SELECT NAME
FROM DPT
WHERE DPT_NO = 10 ;
SELECT NAME
FROM CAT
WHERE CAT_TYPE = ‘RD’;
高效 :
SELECT E.NAME , D.NAME , C.NAME
FROM CAT C , DPT D , EMP E,DUAL X
WHERE NVL(‘X’,X.DUMMY) = NVL(‘X’,E.ROWID(+))
AND NVL(‘X’,X.DUMMY) = NVL(‘X’,D.ROWID(+))
AND NVL(‘X’,X.DUMMY) = NVL(‘X’,C.ROWID(+))
AND E.EMP_NO(+) = 1234
AND D.DEPT_NO(+) = 10
AND C.CAT_TYPE(+) = ‘RD’;
缺點程序可攜性低
6.刪除重覆記錄
DELETE FROM EMP E
WHERE E.ROWID > (SELECT MIN(X.ROWID)
FROM EMP X
WHERE X.EMP_NO = E.EMP_NO);
7.減少對表的查詢
低效
SELECT TAB_NAME
FROM TABLES
WHERE TAB_NAME = ( SELECT TAB_NAME
FROM TAB_COLUMNS
WHERE VERSION = 604)
AND DB_VER= ( SELECT DB_VER
FROM TAB_COLUMNS
WHERE VERSION = 604)
高效
SELECT TAB_NAME
FROM TABLES
WHERE (TAB_NAME,DB_VER)
= ( SELECT TAB_NAME,DB_VER)
FROM TAB_COLUMNS
WHERE VERSION = 604)
8.Update 多Column 例子:
低效:
UPDATE EMP
SET EMP_CAT = (SELECT MAX(CATEGORY) FROM EMP_CATEGORIES),
SAL_RANGE = (SELECT MAX(SAL_RANGE) FROM EMP_CATEGORIES)
WHERE EMP_DEPT = 0020;
高效:
UPDATE EMP
SET (EMP_CAT, SAL_RANGE)
= (SELECT MAX(CATEGORY) , MAX(SAL_RANGE)
FROM EMP_CATEGORIES)
WHERE EMP_DEPT = 0020;
9.使用EXISTS(或NOT EXISTS)通常能提高查詢的效率.
低效:
SELECT *
FROM EMP
WHERE EMPNO > 0
AND DEPTNO IN (SELECT DEPTNO
FROM DEPT
WHERE LOC = ‘MELB’)
高效:
SELECT *
FROM EMP
WHERE EMPNO > 0
AND EXISTS (SELECT ‘X’
FROM DEPT
WHERE DEPT.DEPTNO = EMP.DEPTNO
AND LOC = ‘MELB’)
10.用NOT EXISTS替代NOT IN,為了避免使用NOT IN ,我們可以把它改成外部連接(Outer Joins)或NOT EXISTS.
例如:
SELECT …
FROM EMP
WHERE DEPT_NO NOT IN (SELECT DEPT_NO
FROM DEPT
WHERE DEPT_CAT=’A’);
(方法一: 高效)
SELECT ….
FROM EMP A,DEPT B
WHERE A.DEPT_NO = B.DEPT(+)
AND B.DEPT_NO IS NULL
AND B.DEPT_CAT(+) = ‘A’
(方法二: 最高效)
SELECT ….
FROM EMP E
WHERE NOT EXISTS (SELECT ‘X’
FROM DEPT D
WHERE D.DEPT_NO = E.DEPT_NO
AND DEPT_CAT = ‘A’);
11.用EXISTS替代DISTINCT
低效:
SELECT DISTINCT DEPT_NO,DEPT_NAME FROM DEPT D,EMP E
WHERE D.DEPT_NO = E.DEPT_NO
高效:
SELECT DEPT_NO,DEPT_NAME FROM DEPT D
WHERE EXISTS ( SELECT ‘X’ FROM EMP E
WHERE E.DEPT_NO = D.DEPT_NO);
12.計算目前執行SQL的效能狀況,以下為找出最低效的SQL
SELECT EXECUTIONS , DISK_READS, BUFFER_GETS,
ROUND((BUFFER_GETS-DISK_READS)/BUFFER_GETS,2) Hit_radio,
ROUND(DISK_READS/EXECUTIONS,2) Reads_per_run,
SQL_TEXT
FROM V$SQLAREA
WHERE EXECUTIONS>0
AND BUFFER_GETS > 0
AND (BUFFER_GETS-DISK_READS)/BUFFER_GETS < 0.8
ORDER BY 4 DESC;
13.
Outer Join 外部連接
select d.deptname, e.ename from dept d, emp e where d.empno *= e.enum;
select d.deptname,e.ename from dept d, emp e where d.empno = e.enum (+);
14.檢查 table 或 view 是否存在於 Oracle
SELECT COUNT (table_name) FROM all_tables WHERE UPPER (table_name) = UPPER ('PathologyTest')
SELECT COUNT (view_name) FROM all_views WHERE UPPER (view_name) = UPPER ('v_PathologyTest')
- 9月 09 週二 200813:58
SQL優化過程中常見Oracle HINT的用法
在SQL語句優化過程中,我們經常會用到hint,現總結一下在SQL優化過程中常見Oracle HINT的用法:
1. /*+ALL_ROWS*/
表明對語句塊選擇基於開銷的優化方法,並獲得最佳吞吐量,使資源消耗最小化.
例如:
SELECT /*+ALL+_ROWS*/ EMP_NO,EMP_NAM,DAT_IN FROM BSEMPMS WHERE EMP_NO='SCOTT';
2. /*+FIRST_ROWS*/
表明對語句塊選擇基於開銷的優化方法,並獲得最佳響應時間,使資源消耗最小化.
例如:
SELECT /*+FIRST_ROWS*/ EMP_NO,EMP_NAM,DAT_IN FROM BSEMPMS WHERE EMP_NO='SCOTT';
3. /*+CHOOSE*/
表明如果數據字典中有訪問表的統計信息,將基於開銷的優化方法,並獲得最佳的吞吐量;
表明如果數據字典中沒有訪問表的統計信息,將基於規則開銷的優化方法;
例如:
SELECT /*+CHOOSE*/ EMP_NO,EMP_NAM,DAT_IN FROM BSEMPMS WHERE EMP_NO='SCOTT';
4. /*+RULE*/
表明對語句塊選擇基於規則的優化方法.
例如:
SELECT /*+ RULE */ EMP_NO,EMP_NAM,DAT_IN FROM BSEMPMS WHERE EMP_NO='SCOTT';
5. /*+FULL(TABLE)*/
表明對錶選擇全局掃描的方法.
例如:
SELECT /*+FULL(A)*/ EMP_NO,EMP_NAM FROM BSEMPMS A WHERE EMP_NO='SCOTT';
6. /*+ROWID(TABLE)*/
提示明確表明對指定表根據ROWID進行訪問.
例如:
SELECT /*+ROWID(BSEMPMS)*/ * FROM BSEMPMS WHERE ROWID>='AAAAAAAAAAAAAA'
AND EMP_NO='SCOTT';
7. /*+CLUSTER(TABLE)*/
提示明確表明對指定表選擇簇掃描的訪問方法,它只對簇對像有效.
例如:
SELECT /*+CLUSTER */ BSEMPMS.EMP_NO,DPT_NO FROM BSEMPMS,BSDPTMS
WHERE DPT_NO='TEC304' AND BSEMPMS.DPT_NO=BSDPTMS.DPT_NO;
8. /*+INDEX(TABLE INDEX_NAME)*/
表明對錶選擇索引的掃描方法.
例如:
SELECT /*+INDEX(BSEMPMS SEX_INDEX) USE SEX_INDEX BECAUSE THERE ARE FEWMALE BSEMPMS */ FROM BSEMPMS WHERE SEX='M';
9. /*+INDEX_ASC(TABLE INDEX_NAME)*/
表明對錶選擇索引升序的掃描方法.
例如:
SELECT /*+INDEX_ASC(BSEMPMS PK_BSEMPMS) */ FROM BSEMPMS WHERE DPT_NO='SCOTT';
10. /*+INDEX_COMBINE*/
為指定表選擇位圖訪問路經,如果INDEX_COMBINE中沒有提供作為參數的索引,將選擇出位圖索引的布爾組合方式.
例如:
SELECT /*+INDEX_COMBINE(BSEMPMS SAL_BMI HIREDATE_BMI)*/ * FROM BSEMPMS
WHERE SAL<5000000 emp_no="SCOTT" sex="M" dpt_no="V.DPT_NO">V.AVG_SAL;
20. /*+NO_MERGE(TABLE)*/
對於有可合併的視圖不再合併.
例如:
SELECT /*+NO_MERGE(V) */ A.EMP_NO,A.EMP_NAM,B.DPT_NO FROM BSEMPMS A (SELECT DPT_NO,AVG(SAL) AS AVG_SAL FROM BSEMPMS B GROUP BY DPT_NO) V WHERE A.DPT_NO=V.DPT_NO AND A.SAL>V.AVG_SAL;
21. /*+ORDERED*/
根據表出現在FROM中的順序,ORDERED使ORACLE依此順序對其連接.
例如:
SELECT /*+ORDERED*/ A.COL1,B.COL2,C.COL3 FROM TABLE1 A,TABLE2 B,TABLE3 C WHERE A.COL1=B.COL1 AND B.COL1=C.COL1;
22. /*+USE_NL(TABLE)*/
將指定表與嵌套的連接的行源進行連接,並把指定表作為內部表.
例如:
SELECT /*+ORDERED USE_NL(BSEMPMS)*/ BSDPTMS.DPT_NO,BSEMPMS.EMP_NO,BSEMPMS.EMP_NAM FROM BSEMPMS,BSDPTMS WHERE BSEMPMS.DPT_NO=BSDPTMS.DPT_NO;
23. /*+USE_MERGE(TABLE)*/
將指定的表與其他行源通過合併排序連接方式連接起來.
例如:
SELECT /*+USE_MERGE(BSEMPMS,BSDPTMS)*/ * FROM BSEMPMS,BSDPTMS WHERE BSEMPMS.DPT_NO=BSDPTMS.DPT_NO;
24. /*+USE_HASH(TABLE)*/
將指定的表與其他行源通過哈希連接方式連接起來.
例如:
SELECT /*+USE_HASH(BSEMPMS,BSDPTMS)*/ * FROM BSEMPMS,BSDPTMS WHERE BSEMPMS.DPT_NO=BSDPTMS.DPT_NO;
25. /*+DRIVING_SITE(TABLE)*/
強制與ORACLE所選擇的位置不同的表進行查詢執行.
例如:
SELECT /*+DRIVING_SITE(DEPT)*/ * FROM BSEMPMS,DEPT@BSDPTMS WHERE BSEMPMS.DPT_NO=DEPT.DPT_NO;
26. /*+LEADING(TABLE)*/
將指定的表作為連接次序中的首表.
27. /*+CACHE(TABLE)*/
當進行全表掃描時,CACHE提示能夠將表的檢索塊放置在緩衝區緩存中最近最少列表LRU的最近使用端
例如:
SELECT /*+FULL(BSEMPMS) CAHE(BSEMPMS) */ EMP_NAM FROM BSEMPMS;
28. /*+NOCACHE(TABLE)*/
當進行全表掃描時,CACHE提示能夠將表的檢索塊放置在緩衝區緩存中最近最少列表LRU的最近使用端
例如:
SELECT /*+FULL(BSEMPMS) NOCAHE(BSEMPMS) */ EMP_NAM FROM BSEMPMS;
29. /*+APPEND*/
直接插入到表的最後,可以提高速度.
insert /*+append*/ into test1 select * from test4 ;
30. /*+NOAPPEND*/
通過在插入語句生存期內停止並行模式來啟動常規插入.
insert /*+noappend*/ into test1 select * from test4 ;
- 9月 09 週二 200813:55
基本的Sql編寫注意事項 (轉)
基本的Sql編寫注意事項
- 盡量少用IN操作符,基本上所有的IN操作符都可以用EXISTS代替。
- 不用NOT IN操作符,可以用NOT EXISTS或者外連接+替代。
- Oracle在執行IN子查詢時,首先執行子查詢,將查詢結果放入臨時表再執行主查詢。而EXIST則是首先檢查主查詢,然后運行子查詢直到找到第一個匹配項。NOT EXISTS比NOT IN效率稍高。但具體在選擇IN或EXIST操作時,要根據主子表資料量大小來具體考慮。
- 不用“<>”或者“!=”操作符。對不等於操作符的處理會造成全表掃瞄,可以用“<” or “>”代替。
- Where子句中出現IS NULL或者IS NOT NULL時,Oracle會停止使用索引而執行全表掃瞄。可以考慮在設計表時,對索引列設置為NOT NULL。這樣就可以用其他操作來取代判斷NULL的操作。
- 當通配符“%”或者“_”作為查詢字符串的第一個字符時,索引不會被使用。
- 對於有連接的列“||”,最后一個連接列索引會無效。盡量避免連接,可以分開連接或者使用不作用在列上的函數替代。
- 如果索引不是基於函數的,那麼當在Where子句中對索引列使用函數時,索引不再起作用。
- Where子句中避免在索引列上使用計算,否則將導致索引失效而進行全表掃瞄。
- 對資料類型不同的列進行比較時,會使索引失效。
- 用“>=”替代“>”。
- UNION操作符會對結果進行篩選,消除重復,資料量大的情況下可能會引起磁盤排序。如果不需要刪除重復記錄,應該使用UNION ALL。
- Oracle從下到上處理Where子句中多個查詢條件,所以表連接語句應寫在其他Where條件前,可以過濾掉最大數量記錄的條件必須寫在Where子句的末尾。
- Oracle從右到左處理From子句中的表名,所以在From子句中包含多個表的情況下,將記錄最少的表放在最后。(只在採用RBO優化時有效,下文詳述)
- Order By語句中的非索引列會降低性能,可以通過添加索引的方式處理。嚴格控制在Order By語句中使用表達式。
- 不同區域出現的相同的Sql語句,要保證查詢字符完全相同,以利用SGA共享池,防止相同的Sql語句被多次分析。
- 多利用內部函數提高Sql效率。
- 當在Sql語句中連接多個表時,使用表的別名,並將之作為每列的前置碼。這樣可以減少解析時間。
需要注意的是,隨著Oracle的昇級,查詢優化器會自動對Sql語句進行優化,某些限制可能在新版本的Oracle下不再是問題。尤其是採用CBO(Cost-Based Optimization,基於代價的優化方式)時。
我們可以總結一下可能引起全表掃瞄的操作:
- 在索引列上使用NOT或者“<>”;
- 對索引列使用函數或者計算;
- NOT IN操作;
- 通配符位於查詢字符串的第一個字符;
- IS NULL或者IS NOT NULL;
- 多列索引,但它的第一個列並沒有被Where子句引用;
Oracle優化器
Oracle優化器(Optimizer)是Oracle在執行SQL之前分析語句的工具。
Oracle的優化器有兩種優化方式:基於規則的(RBO)和基於代價的(CBO)。
- RBO:優化器遵循Oracle內部預定的規則。
- CBO:依據語句執行的代價,主要指對CPU和記憶體的占用。優化器在判斷是否使用CBO時,要參照表和索引的統計資訊。統計資訊要在對表做analyze后才會有。Oracle8及以后版本,推荐用CBO方式。
Oracle優化器的優化模式主要有四種:
- Rule:基於規則;
- Choose:預設模式。根據表或索引的統計資訊,如果有統計資訊,則使用CBO方式;如果沒有統計資訊,相應列有索引,則使用RBO方式。
- First rows:與Choose類似。不同的是如果表有統計資訊,它將以最快的方式返回查詢的前幾行,以獲得最佳響應時間。
- All rows:即完全基於Cost的模式。當一個表有統計資訊時,以最快方式返回表所有行,以獲得最大吞吐量。沒有統計資訊則使用RBO方式。
設定優化模式的方式
- Instance級別:在init<SID>.ora文件中設定OPTIMIZER_MODE;
- Session級別:通過SQL> ALTER SESSION SET OPTIMIZER_MODE=;來設定。
- 語句級別:通過SQL> SELECT /*+ALL+_ROWS*/ ……;來設定。可用的HINT包括/*+ALL_ROWS*/、/*+FIRST_ROWS*/、/*+CHOOSE*/、/*+RULE*/ 等。
要注意的是,如果表有統計資訊,則可能造成語句不走索引的結果。可以用SQL>ANALYZE TABLE table_name DELETE STATISTICS; 刪除索引。
對列和索引更新統計資訊的SQL:
SQL> ANALYZE TABLE table_name COMPUTE STATISTICS;
SQL> ANALYZE INDEX index_name ESTIMATE STATISTICS;
- 9月 08 週一 200813:40
利用SQL查看ORACLE Debug訊息
select to_char(timestamp, 'DD-MON-YY HH24:MI:SS'),
message_text,
module,
log_sequence
from fnd_log_messages
WHERE trunc(timestamp) = trunc(sysdate)
AND process_id = (SELECT os_process_id
FROM fnd_concurrent_requests
WHERE request_id = &p_request_id)
AND module not like 'fnd%'
ORDER BY log_sequence;
- 9月 05 週五 200816:15
SQL 日期的應用 (轉)
oracle SQL裡常用的時間函數,經典推薦
相信很多人都有過統計某些數據的經歷,比如,要統計財務的情況,可能要按每年,每季度,每月,甚至每個星期來分別統計。 那在oracle中應該怎麼來寫sql語句呢,這個時候Oracle的日期函數會給我們很多幫助。
常用日期型函數
1。 Sysdate當前日期和時間
SQL> Select sysdate from dual;
SYSDATE
----------
21-6月-05
2。 Last_day本月最後一天
SQL> Select last_day(sysdate) from dual;
LAST_DAY(S
----------
30-6月-05