建议:避免通过DUAL表赋值。
说明:过多的对DUAL表的访问,导致调用该表的等待时间事件比较长。比如取系统时间之类的操作,往一个表插入记录等。 示例:
错误的用法:
SELECT SYSDATE INTO v_Date FROM DUAL
正确的用法:
v_Date := SYSDATE
错误的用法:
INSERT INTO TABLENAME(FIELD1, FIELD2, FIELD3) SELECT '2', SYSDATE, SUSBTR(v_Name, 1, 30) FROM DUAL;
正确的用法:
INSERT INTO TABLENAME(FIELD1, FIELD2, FIELD3) VALUES('2', SYSDATE, SUSBTR(v_Name, 1, 30));
7.2 禁止
规则:严禁用系统表空间作为用户默认表空间;严禁在系统表空间上创建用户数据库对象;严禁在SYSTEM/SYS等系统用户下,创建用户数据库对象。
规则:SQL语句的WHERE子句中应尽可能将字段放在等式左边,将计算操作放在等式的右边,除非是要屏蔽该字段的的索引,否则禁止字段参与表达式运算。
说明:任何对字段的操作都将造成此字段上的索引被屏蔽,导致全表扫描,这里所谓的操作包括数据库函数、计算表达式等等。 示例:
错误的用法:
SELECT SOME_FIELD FROM TABLENAME
WHERE NUM_FIELD / 30 < 1000
正确的用法:
2013-03-28
第36页,共71页
SELECT SOME_FIELD FROM TABLENAME
WHERE NUM_FIELD < 1000 * 30
错误的用法:
SELECT SOME_FIELD FROM TABLENAME
WHERE TO_CHAR(LOGDATE, 'YYYYMMDD') = '19991201'
正确的用法:
SELECT SOME_FIELD FROM TABLENAME
WHERE LOGDATE >= TO_DATE('19991201', 'YYYYMMDD') AND LOGDATE < TO_DATE('19991202', 'YYYYMMDD')
规则:SQL语句的WHERE子句中每个条件的操作符两边类型应相同,禁止潜在的数据类型转换。
说明:潜在的字段数据类型转换将造成索引被屏蔽,导致全表扫描。例如将字符型数据与数值型数据比较,ORACLE会自动将字符类型字段用TO_NUMBER函数进行转换。 示例:
错误的用法:
表TABLENAME中的列STRING_FIELD是字符型(VARCHAR),则以下语句存在类型转换:
SELECT SOMEFIELD FROM TABLENAME
WHERE STRING_FIELD > 10
正确的用法:
SELECT SOMEFIELD FROM TABLENAME
WHERE STRING_FIELD > '10'
规则:SQL语句的WHERE子句中避免使用IN操作,严禁使用NOT IN操作。
说明:在SQL语句中,能用表连接尽量使用表连接,不能使用表连接则使用EXISTS,严禁使用IN。 示例:
2013-03-28
第37页,共71页
错误的用法:
SELECT SOME_FIELD FROM TABLE1 WHERE FIELD1 IN (
SELECT FIELD2 FROM TABLE2 )
正确的用法:
SELECT T1.SOME_FIELD FROM TABLE1 T1, TABLE2 T2 WHERE T1.FIELD1 = T2.FIELD2
错误的用法:
SELECT SOME_FIELD FROM TABLE1
WHERE FIELD1 NOT IN (
SELECT FIELD2 FROM TABLE2 )
正确的用法:
SELECT SOME_FIELD FROM TABLE1 T1 WHERE NOT EXISTS (
SELECT 1
FROM TABLE2 T2
WHERE T2.FIELD2 = T1.FIELD1 )
规则:禁止对VARCHAR(2000)之类的大字段值进行ORDER BY、DISTINCT、GROUP BY、UNION之类的操作。
说明:此类操作将消耗大量的CPU和内存资源。
规则:禁止在没有事务的存储过程和代码中,随意使用COMMIT和ROLLBACK。 说明:过多多余的ROLLBACK和COMMIT容易引起数据库的同步日志等待事件,对系统的性能有影响,下面语句中的COMMIT和ROLLBACK就是多余的。 示例:
2013-03-28
第38页,共71页
错误的用法:
CREATE OR REPLACE PROCEDURE P_MS_QUERYBYSERIALNO (
i_SerialNo VARCHAR2, -- 工单流水号 rCursor OUT PACK_SERVICE.t_RetDataSet -- 返回结果集 ) AS BEGIN
OPEN rCursor
FOR SELECT b.STAFFNO AS STAFFNO, DECODE(b.COMMITRESULT, 0, '成功', '失败') AS COMMITRESULT FROM T_MS_SENDLOGHIS a, T_MS_INTERFACECALLED b WHERE b.SERIALNO = i_SerialNo;
COMMIT;
EXCEPTION
WHEN OTHERS THEN ROLLBACK; END;
正确的用法:
CREATE OR REPLACE PROCEDURE P_MS_QUERYBYSERIALNO (
i_SerialNo VARCHAR2, -- 工单流水号 rCursor OUT PACK_SERVICE.t_RetDataSet -- 返回结果集 ) IS BEGIN
OPEN rCursor
FOR SELECT b.STAFFNO AS STAFFNO, DECODE(b.COMMITRESULT, 0, '成功', '失败') AS COMMITRESULT FROM T_MS_INTERFACECALLED b WHERE b.SERIALNO = i_SerialNo;
EXCEPTION
WHEN OTHERS THEN OPEN rCursor
FOR SELECT '成功' AS STAFFNO, '成功' AS COMMITRESULT FROM DUAL WHERE 1 = 2; END; 2013-03-28
第39页,共71页
规则:禁止利用SQL语句做一些业务逻辑的判断或操作。 示例:
错误的用法:
SELECT STAFFNO, STAFFNAME FROM T_PUB_STAFF
WHERE (i_StaffNo IS NULL OR STAFFNO = i_StaffNo)
AND (i_StaffName IS NULL OR STAFFNAME LIKE '%' || i_StaffName || '%')
错误分析:上面的SQL语句中,利用SQL引擎对变量的值进行判断,导致在使用过程中,对该表进行全表扫描。
正确的用法:通过代码中对变量的值进行判断然后决定执行对应的SQL语句。
规则:禁止在生产系统,直接用PL/SQL Developer或TOAD之类的工具中直接调试存储过程。
规则:禁止在PL/SQL Developer中执行SELECT * FROM TABLE_NAME FOR UPDATE,然后点击锁图标方式,再编辑数据的方式进行更新数据库中的数据。
2013-03-28 第40页,共71页
百度搜索“77cn”或“免费范文网”即可找到本站免费阅读全部范文。收藏本站方便下次阅读,免费范文网,提供经典小说综合文库ORACLE编程规范(8)在线全文阅读。
相关推荐: