書寫格式 示例代碼
存儲過程SQL文書寫格式例
select
c
dealerCode
round(sum(c
submitSubletAmountDLR + c
submitPartsAmountDLR + c
submitLaborAmountDLR) / count(*)
) as avg
decode(null
x
xx
CNY
)
from (
select
a
dealerCode
a
submitSubletAmountDLR
a
submitPartsAmountDLR
a
submitLaborAmountDLR
from SRV_TWC_F a
where (to_char(a
ORIGSUBMITTIME
yyyy/mm/dd
) >=
Date Range(start)
and to_char(a
ORIGSUBMITTIME
yyyy/mm/dd
) <=
Date Range(end)
and nvl(a
deleteflag
) <>
)
union all
select
b
dealerCode
b
submitSubletAmountDLR
b
submitPartsAmountDLR
b
submitLaborAmountDLR
from SRV_TWCHistory_F b
where (to_char(b
ORIGSUBMITTIME
yyyy/mm/dd
) >=
Date Range(start)
and to_char(b
ORIGSUBMITTIME
yyyy/mm/dd
) <=
Date Range(end)
and nvl(b
deleteflag
) <>
)
) c
group by c
dealerCode
order by avg desc;
Java source裡的SQL字符串書寫格式例
strSQL =
insert into Snd_FinanceHistory_Tb
+
(DEALERCODE
+
REQUESTSEQUECE
+
HANDLETIME
+
JOBFLAG
+
FRAMENO
+
INMONEY
+
REMAINMONEY
+
DELETEFLAG
+
UPDATECOUNT
+
CREUSER
+
CREDATE
+
HONORCHECKNO
+
SEQ)
+
values (
+ draftInputDetail
dealerCode +
+
+ draftInputDetail
requestsequece +
+
sysdate
+
+
+ frameNO +
+ requestMoney +
+ remainMoney +
+
+
+
+ draftStruct
employeeCode +
+
sysdate
+
+ draftInputDetail
honorCheckNo +
+ index +
)
;
)
縮進
對於存儲過程文件
縮進為
個空格
對於Java source裡的SQL字符串
不可有縮進
即每一行字符串不可以空格開頭
)
換行
>
Select/From/Where/Order by/Group by等子句必須另其一行寫
>
Select子句內容如果只有一項
與Select同行寫
>
Select子句內容如果多於一項
每一項單獨占一行
在對應Select的基礎上向右縮進
個空格(Java source無縮進)
>
From子句內容如果只有一項
與From同行寫
>
From子句內容如果多於一項
每一項單獨占一行
在對應From的基礎上向右縮進
個空格(Java source無縮進)
>
Where子句的條件如果有多項
每一個條件占一行
以AND開頭
且無縮進
>
(Update)Set子句內容每一項單獨占一行
無縮進
>
Insert子句內容每個表字段單獨占一行
無縮進
values每一項單獨占一行
無縮進
>
SQL文中間不允許出現空行
>
Java source裡單引號必須跟所屬的SQL子句處在同一行
連接符(
+
)必須在行首
)
空格
>
SQL內算數運算符
邏輯運算符連接的兩個元素之間必須用空格分隔
>
逗號之後必須接一個空格
>
關鍵字
保留字和左括號之間必須有一個空格
不等於統一使用<> Oracle認為
!=
和
<>
是等價的
都代表不等於的意義
為了統一
不等於一律使用
<>
表示
使用表的別名 數據庫查詢
必須使用表的別名
SQL文對表字段擴展的兼容性 在Java source裡使用Select *時
嚴禁通過getString(
)的形式得到查詢結果
必須使用getString(
字段名
)的形式
使用Insert時
必須指定插入的字段名
嚴禁不指定字段名直接插入values
減少子查詢的使用 子查詢除了可讀性差之外
還在一定程度上影響了SQL運行效率
請盡量減少使用子查詢的使用
用其他效率更高
可讀性更好的方式替代
適當添加索引以提高查詢效率 適當添加索引可以大幅度的提高檢索速度
請參看ORACLE SQL性能優化系列
對數據庫表操作的特殊要求 本項目對數據庫表的操作還有以下特殊要求
)
以邏輯刪除替代物理刪除
注意
現在數據庫表中數據沒有物理刪除
只有邏輯刪除
以deleteflag字段作為刪除標志
deleteflag=
代表此記錄被邏輯刪除
因此在查詢數據時必須考慮deleteflag的因素
deleteflag的標准查詢條件
NVL(deleteflag
) <>
)
增加記錄狀態字段
數據庫中的每張表基本都有以下字段
DELETEFLAG
UPDATECOUNT
CREDATE
CREUSER
UPDATETIME
UPDATEUSER
要注意在對標進行操作時必須考慮以下字段
插入一條記錄時要置DELETEFLAG=
UPDATECOUNT=
CREDATE=sysdate
CREUSER=登錄User
查詢一條記錄時要考慮DELETEFLAG
如果有可能對此記錄作更新時還要取得UPDATECOUNT作同步檢查
修改一條記錄時要置UPDATETIME=sysdate
UPDATEUSER=登錄User
UPDATECOUNT=(UPDATECOUNT+
) mod
刪除一條記錄時要置DELETEFLAG=
)
歷史表
數據庫裡部分表還存在相應的歷史表
比如srv_twc_f和srv_twchistory_f
在查詢數據時除了檢索所在表之外
還必須檢索相應的歷史表
對二者的結果做Union(或Union All)
用執行計劃分析SQL性能 EXPLAIN PLAN是一個很好的分析SQL語句的工具
它可以在不執行SQL的情況下分析語句
通過分析
我們就可以知道ORACLE是怎樣連接表
使用什麼方式掃描表(索引掃描或全表掃描)
以及使用到的索引名稱
按照從裡到外
從上到下的次序解讀分析的結果
EXPLAIN PLAN的分析結果是用縮進的格式排列的
最內部的操作將最先被解讀
如果兩個操作處於同一層中
帶有最小操作號的將首先被執行
目前許多第三方的工具如PLSQL Developer和TOAD等都提供了極其方便的EXPLAIN PLAN工具
PG需要將自己添加的查詢SQL文記入log
然後在EXPLAIN PLAN中進行分析
盡量減少全表掃描
ORACLE SQL性能優化系列 選擇最有效率的表名順序(只在基於規則的優化器中有效) ORACLE的解析器按照從右到左的順序處理FROM子句中的表名
因此FROM子句中寫在最後的表(基礎表driving table)將被最先處理
在FROM子句中包含多個表的情況下
必須選擇記錄條數最少的表作為基礎表
當ORACLE處理多個表時
會運用排序及合並的方式連接它們
首先
掃描第一個表(FROM子句中最後的那個表)並對記錄進行排序
然後掃描第二個表(FROM子句中最後第二個表)
最後將所有從第二個表中檢索出的記錄與第一個表中合適記錄進行合並
例如:
表 TAB
條記錄
表 TAB
條記錄
選擇TAB
作為基礎表 (最好的方法)
select count(*) from tab
tab
執行時間
秒
選擇TAB
作為基礎表 (不佳的方法)
select count(*) from tab
tab
執行時間
秒
如果有
個以上的表連接查詢
那就需要選擇交叉表(intersection table)作為基礎表
交叉表是指那個被其他表所引用的表
例如:
EMP表描述了LOCATION表和CATEGORY表的交集
SELECT *
FROM LOCATION L
CATEGORY C
EMP E
WHERE E
EMP_NO BETWEEN
AND
AND E
CAT_NO = C
CAT_NO
AND E
LOCN = L
LOCN
將比下列SQL更有效率
SELECT *
FROM EMP E
LOCATION L
CATEGORY C
WHERE E
CAT_NO = C
CAT_NO
AND E
LOCN = L
LOCN
AND E
EMP_NO BETWEEN
AND
WHERE子句中的連接順序 ORACLE采用自下而上的順序解析WHERE子句
根據這個原理
表之間的連接必須寫在其他WHERE條件之前
那些可以過濾掉最大數量記錄的條件必須寫在WHERE子句的末尾
例如
(低效
執行時間
秒)
SELECT *
FROM EMP E
WHERE SAL >
AND JOB =
MANAGER
AND
< (SELECT COUNT(*) FROM EMP WHERE MGR=E
EMPNO);
(高效
執行時間
秒)
SELECT *
FROM EMP E
WHERE
< (SELECT COUNT(*) FROM EMP WHERE MGR=E
EMPNO)
AND SAL >
AND JOB =
MANAGER
;
SELECT子句中避免使用* 當你想在SELECT子句中列出所有的COLUMN時
使用動態SQL列引用
*
是一個方便的方法
不幸的是
這是一個非常低效的方法
實際上
ORACLE在解析的過程中
會將
*
依次轉換成所有的列名
這個工作是通過查詢數據字典完
From:http://tw.wingwit.com/Article/program/Oracle/201311/18246.html