本规范规定了SQL DQL和DML语言的编写总则,从书写格式、性能优化两方面归纳了SQL 书写的具体要求,并给出SQL语句示例。
//正确的示例
SELECT
list.manifest_no,
list.bill_no,
stat.list_stat
FROM
mft_list list,
list_stat stat
WHERE
list.manifest_no = stat.manifest_no
AND list.bill_no = stat.list_no;
SELECT emp_name
FROM emp
WHERE emp_no = :B1; //Bind value: 123
SELECT emp_name
FROM emp
WHERE emp_no = :B1; //Bind value: 987
SELECT emp_name
FROM emp
WHERE emp_no = 123;
SELECT emp_name
FROM emp
WHERE emp_no = 987;
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;
SELECT
list.manifest_no,
list.bill_no,
STAT.list_stat
FROM
mft_list list,
list_stat STAT
WHERE
list.manifest_no = STAT.manifest_no
AND list.BILL_NO = STAT.list_no;
ALTER SEQUENCE MANIFEST_NO CACHE 200;
SELECT manifest_no.nextval FROM DUAL;
SELECT
list.manifest_no,
list.list_no,
stat.list_stat
from
mft_list list,
list_stat stat
where
list.manifest_no = stat.manifest_no
AND list.bill_no = stat.list_no;
INSERT INTO employees
(
employee_name,
date,
employee_age
)
VALUES
(
employees_seq.nextval,
'John',
to_date (SYSDATE),
30
)
SELECT
list.manifest_no,
list.list_no,
s.list_stat
FROM
mft_list list,
list_stat s
WHERE
list.manifest_no = s.manifest_no
AND list.bill_no = s.list_no;
//存储过程SQL文书写格式的正确示例
SELECT
result.dealerCode,
ROUND (SUM (result.submitsubletamountdlr + result.submitpartsamountdlr
+ result.submitlaboramountdlr) / COUNT (*), 2) as avg,
DECODE (null, 'x', 'xx', 'CNY')
FROM
(SELECT
twc.dealerCode,
twc.submitsubletamountdlr,
twc.submitpartsamountdlr,
twc.submitlaboramountdlr
FROM srv_twc_f twc
WHERE
(twc.origsubmittime >= TO_DATE ('Date Range(start)', 'yyyy/mm/dd')
AND twc.origsubmittime <= TO_DATE ('Date Range(end)', 'yyyy/mm/dd')
AND NVL (twc.deleteflag, '0') <> '1')
UNION ALL
SELECT
history.dealercode,
history.submitsubletamountdlr,
history.submitpartsamountdlr,
history.submitlaboramountdlr
FROM srv_twchistory_f history
WHERE
(history.origsubmittime >= TO_DATE ('Date Range(start)', 'yyyy/mm/dd')
AND history.origsubmittime <= TO_DATE ('Date Range(end)','yyyy/mm/dd')
AND NVL (history.deleteflag,'0') <> '1')) result
GROUP BY result.dealerCode
ORDER BY avg DESC;)
//SELECT语句书写的正确示例
SELECT bill_no,
FROM mft_list
WHERE manifest_no =‘000000000000000007’;
SELECT
list.manifest_no,
list.list_no,
stat.list_stat
FROM
mft_list list,
list_stat stat
WHERE
list.manifest_no = stat.manifest_no
AND stat.stat != 2;
//SELECT语句书写的正确示例
UPDATE list_stat
SET
list_stat = '2',
parent = '0'
WHERE list_no = 'bill010';
//INSERT语句书写的正确示例
INSERT INTO list_stat
(
list_no,
list_stat,
parent,
manifest_no,
div_flag
)
VALUES
(
'bill020',
'1',
'0',
'000000000000007807',
'0'
);
SELECT
list.manifest_no,
list.list_no,
stat.list_stat
FROM
mft_list list,
list_stat stat
WHERE
list.manifest_no = stat.manifest_no
AND list.bill_no= stat.list_no;
SELECT
COUNT(DECODE(dept_no, '0020','X',NULL)) d0020_count,
COUNT(DECODE(dept_no, '0030','X',NULL)) d0030_count,
SUM(DECODE(dept_no, 0020, salary, NULL)) d0020_sal,
SUM(DECODE(dept_no, 0030, salary, NULL)) d0030_sal
FROM emp
WHERE emp_name LIKE 'SMITH%';
SELECT
list.manifest_no,
list.list_no,
stat.list_stat
FROM
mft_list list,
list_stat stat
WHERE
list.manifest_no = stat.manifest_no
AND list.bill_no = stat.list_no
AND stat.stat <> ‘2’
AND parent != ‘0’;
BEGIN
...
/* Compute a 15% bonus for top-rated employees. */
IF rating > 90 THEN
bonus := salary * 0.15 /* bonus is based on salary */
ELSE
bonus := 0;
END IF;
...
/* The following line computes the area of a
circle using pi, which is the ratio between
the circumference and diameter. */
area := pi * radius**2;
END;
//SQL拼串语句书写的正确示例
string tmpsql = "SELECT i_e_flag, i_e_date, ship_id FROM mft_head WHERE manifest_no =:MANIFEST_NO";
StringBuilder sqlStr = "SELECT manifest_no, i_e_flag, i_e_date, ship_id FROM mft_head "
+ "WHERE manifest_no = '"+ manifestNo + "'"
+ "AND ship_id = '"+ shipId + "'";
//一般情况下,效率较低。
SELECT
COUNT (*),
SUM (salary)
FROM emp
WHERE
dept_no = '0020'
AND emp_name LIKE 'SMITH%';
SELECT
COUNT (*),
SUM (salary)
FROM emp
WHERE
dept_no = '0030'
AND emp_name LIKE 'SMITH%';
//一般情况下,效率较高。
SELECT
COUNT(DECODE(dept_no, '0020', 'X', NULL)) d0020_count,
COUNT(DECODE(dept_no, '0030', 'X', NULL)) d0030_count,
SUM(DECODE(dept_no, '0020', salary, NULL)) d0020_sal,
SUM(DECODE(dept_no, '0030', salary, NULL)) d0030_sal
FROM emp
WHERE emp_name LIKE 'SMITH%';
其中:X表示任何字符或字符串。
类似的,DECODE 还可用于GROUP BY 和 ORDER BY 子句中。
//3个简单的查询。
SELECT NAME
FROM EMP
WHERE EMP_NO = 1234;
SELECT NAME
FROM DPT
WHERE DPT_NO = 10 ;
SELECT NAME
FROM CAT
WHERE CAT_TYPE = ‘RD’;
//上面的3个查询可以被合并成一个。
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’;
//一般情况下,效率较低。
SELECT
region,
AVG (log_size)
FROM location
GROUP BY region
HAVING region <> 'SYDNEY'
AND region <> 'PERTH'
//一般情况下,效率较高。
SELECT
region,
AVG (log_size)
FROM location
WHERE
region <> 'SYDNEY'
AND region <> 'PERTH'
GROUP BY region
//一般情况下,效率较低。
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')
//一般情况下,效率较低。
SELECT …
FROM emp
WHERE dept_no NOT IN ( SELECT dept_no
FROM dept
WHERE dept_cat = 'A');
//一般情况下,效率较高。
SELECT …
FROM employee emp, department dept
WHERE emp.dept_no = dept.dept_no(+)
AND dept.dept_no IS NULL
AND dept.dept_cat(+) = 'A'
//一般情况下最高效。
SELECT …
FROM employee emp
WHERE NOT EXISTS ( SELECT 'X'
FROM department dept
WHERE emp.dept_no = dept.dept_no)
//一般情况下,效率较低。
SELECT ename
FROM employee emp
WHERE EXISTS ( SELECT 'X'
FROM department dept
WHERE dept_no = emp.dept_no
AND dept_cat = 'A');
//一般情况下,效率较高。
SELECT ename
FROM department dept, employee emp
WHERE dept.dept_no = emp.dept_no
AND dept.dept_cat = 'A';
一般情况下,使用 EXIST 子句替代 DISTINCT 子句可提高性能。
//一般情况下,效率较低。
SELECT
DISTINCT dept.dept_no,
dept.dept_name
FROM
departement dept,
employee emp
WHERE dept.dept_no = emp.dept_no
//一般情况下,效率较高。
SELECT
dept_no,
dept_name
FROM department dept
WHERE EXISTS ( SELECT 'X'
FROM employee emp
WHERE emp.dept_no = dept.dept_no);
// WHERE语句中使用索引的优化。红色的表示没有成功使用索引,蓝色的表示成功使用索引。
SELECT
acc_name,
trans_date,
amount
FROM transaction
WHERE SUBSTR(account_name,1,7) = 'CAPITAL';
SELECT
acc_name,
trans_date,
amount
FROM transaction
WHERE account_name LIKE 'CAPITAL%';
SELECT
acc_name,
trans_date,
amount
FROM transaction
WHERE amount <> 0;
SELECT
acc_name,
trans_date,
amount
FROM transaction
WHERE amount > 0;
SELECT
acc_name,
trans_date,
amount
FROM transaction
WHERE TRUNC(trans_date) = TRUNC(SYSDATE);
SELECT
acc_name,
trans_date,
amount
FROM transaction
WHERE trans_date BETWEEN TRUNC(SYSDATE) AND TRUNC(SYSDATE) + .99999;
SELECT
acc_name,
trans_date,
amount
FROM transaction
WHERE acc_name || acc_type = 'AMEXA';
SELECT
acc_name,
trans_date,
amount
FROM transaction
WHERE
acc_name = 'AMEX'
AND acc_type = 'A';
SELECT
acc_name,
trans_date,
amount
FROM transaction
WHERE amount + 3000 < 5000;
SELECT
acc_name,
trans_date,
amount
FROM transaction
WHERE amount < 5000 - 3000;