ORACLE编程规范

更新时间:2023-03-08 17:21:58 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

ORACLE编程规范

目 录

第1章 范围和简介 ....................................................................................................... 5 1.1 简介 ........................................................................................................................ 5 1.2 范围 ........................................................................................................................ 5 1.3 关键词 ..................................................................................................................... 5 1.4 术语和定义 ............................................................................................................. 5 第2章 文件格式及命名 ................................................................................................ 6 2.1 文件格式 ................................................................................................................. 6 2.2 文件命名 ................................................................................................................. 6 第3章 书写规范 ........................................................................................................... 7 3.1 大小写风格 ............................................................................................................. 7 3.2 缩进风格 ................................................................................................................. 8 3.3 空格及换行 ........................................................................................................... 12 3.4 创建表 ................................................................................................................... 15 3.5 创建过程/函数/包 .................................................................................................. 16 第4章 命名规范 ......................................................................................................... 17 第5章 注释规范 ......................................................................................................... 22 第6章 常用语法 ......................................................................................................... 26 6.1 变量声明 ............................................................................................................... 26 6.2 返回值 ................................................................................................................... 26 6.3 符号* ..................................................................................................................... 26 6.4 包的使用 ............................................................................................................... 27 6.5 绑定变量 ............................................................................................................... 27 6.6 异常处理 ............................................................................................................... 29 6.7 事务控制 ............................................................................................................... 30 6.8 游标使用 ............................................................................................................... 30 6.9 代码规模 ............................................................................................................... 32 第7章 SQL建议与约束 ............................................................................................. 33 7.1 建议 ...................................................................................................................... 33 7.2 禁止 ...................................................................................................................... 36 第8章 应用设计及性能调整 ....................................................................................... 41 8.1 日志表设计 ........................................................................................................... 41 8.1.1 特点描述 ......................................................................................................... 41 8.1.2 数据分析 ......................................................................................................... 42 8.1.3 设计方案 ......................................................................................................... 42 8.1.4 注意事项 ......................................................................................................... 45 8.2 并发事务表设计 .................................................................................................... 46 8.2.1 特点描述 ......................................................................................................... 46 8.2.2 数据分析 ......................................................................................................... 46 8.2.3 设计方案 ......................................................................................................... 46

2013-03-28 第2页,共71页

8.2.4 注意事项 ......................................................................................................... 50 8.3 分区的设计 ........................................................................................................... 51 8.3.1 分区的优点 ..................................................................................................... 52 8.3.2 RANGE分区的应用场景 ................................................................................ 53 8.3.3 HASH分区的应用场景 ................................................................................... 54 8.3.4 分区注意事项 .................................................................................................. 55 8.4 索引设计 ............................................................................................................... 55 8.5 性能参数 ............................................................................................................... 61 8.5.1 序列对性能的影响 .......................................................................................... 61 8.5.2 EXTENT对数据插入性能的影响 .................................................................... 62 8.5.3 INITRANS对性能的影响 ................................................................................ 63 8.6 常见等待事件 ........................................................................................................ 64 第9章 开发工具 ......................................................................................................... 65 9.1 UltraEdit-32 .......................................................................................................... 65 9.2 PL/SQL Developer ............................................................................................... 65 9.3 TOAD ................................................................................................................... 65 9.4 PowerDesigner ..................................................................................................... 66 第10章 数据库代码走读CheckList ............................................................................. 67 第11章 附录 ................................................................................................................ 70 11.1 常见模块缩写表 .............................................................................................. 70 11.2 常用词缩写表 .................................................................................................. 70

2013-03-28 第3页,共71页

表目录

表1 表2 表3 表4 表5 表6

大小写规范表 .......................................................................................................... 7 对象前缀表 ........................................................................................................... 17 ORACLE系统对象使用前缀表 ............................................................................. 18 参数、变量、常量、异常等前缀表 ....................................................................... 19 常见模块缩写表 .................................................................................................... 70 常用词缩写表 ........................................................................................................ 70

2013-03-28 第4页,共71页

第1章 范围和简介

1.1 简介

本规范是针对关系型数据库ORACLE的相关特性,拟定的用于指导和规范相关开发过程的规范,其旨在通过该规范的约束和建议,使开发人员可以在他们所编写的代码中保持统一正确的风格,提供代码的可读性以及减少出现错误的几率。

1.2 范围

本规范仅适用于关系型数据库系统ORACLE以及其对应的PL/SQL脚本语言。

1.3 关键词

编程规范、数据库、ORACLE、PL/SQL

1.4 术语和定义

本规范采用以下的术语描述:

★ 规则:编程时强制必须遵守的原则。 ★ 建议:编程时必须加以考虑的原则。 ★ 说明:对此规则或建议进行必要的解释。 ★ 示例:对此规则或建议从正、反两个方面给出。

2013-03-28 第5页,共71页

第2章 文件格式及命名

2.1 文件格式

规则:数据库脚本文件的文件格式必须为纯文本,不允许使用包含格式文本的文件格式。

2.2 文件命名

规则:每个数据库脚本文件命名请参照下列描述:

1.表:TableName.tab 2.函数:FunctionName.fnc 3.存储过程:ProcedureName.prc 4.包规范:PackageName.spc 5.包体:PackageName.bdy

2013-03-28 第6页,共71页

第3章 书写规范

3.1 大小写风格

规则:数据库脚本中涉及到的各种保留字、关键字、操作符、数据类型、标识符、对象、字段、变量、常量等的大小写风格必须遵循以下规范:

表1

文字类型 ORACLE保留字(Reserved Word) 大小写规范表 大小写 大写 示例 IDENTIFIED、INITIAL、LONG、MAXEXTENTS、RENAME、ROWNUM、SYSDATE、VARCHAR2 ANALYZE、AUTOEXTEND、COMPILE、DBA、EXTENT、INSTANCE、MAXTRANS、SAVEPOINT、TABLESPACE ADD、BETWEEN、CREATE、DISTINCT、DROP、FROM、SESSION、SELECT、TABLE、UPDATE、VARCHAR BEGIN、COMMIT、CONSTRAINT、COUNT、CURSOR、DECLARE、EXECUTE、PRIMARY、SUM、TRANSACTION ARRAY、BOOLEAN、DATABASE、DO、EXIT、RAISE、SAVEPOINT、RUN、WHILE、XOR ALL、AND、ANY、ESCAPE、EXISTS、OR、UNION INT、NUMBER、DATE USER$、DBA_JOBS、DECODE、SUBSTR、DBMS_OUTPUT、PUT_LINE、NO_DATA_FOUND

第7页,共71页

ORACLE关键字(Keywords) 大写 ANSI SQL保留字(Reserved Word) 大写 ANSI SQL关键字(Keywords) 大写 PL/SQL保留字(Reserved Word) 大写 操作符(Operators) 大写 数据类型(Data Types) 系统数据库对象(System Tables、Views、Functions、Packages、Package Methods、Exceptions) 2013-03-28

大写 大写

自定义数据库对象(User Objects) 逻辑首字母大写 T_Table_Name、F_Function_Name、P_Procedure_Name User_Name、Acct_Item_ID c_BeginDate、c_EndDate v_BeginDate、v_FaxNumber、v_StaffAuth 字段名(Field) 常量(Constants) 变量(Variable) 逻辑首字母大写 逻辑首字母大写 逻辑首字母大写 说明:

? ORACLE的关键字和保留字请参见视图V$RESERVED_WORDS;

? 上表中需要大写的关键字/保留字,可以录入UltraEdit的wordfile.txt,在使用

UltraEdit开发时输入这些关键字保留字后会自动变为大写。

3.2 缩进风格

规则:脚本代码块采用缩进风格书写,保证代码清晰易读,风格一致。缩进格数统一为4个空格,但需要关键字右对齐或者参数/字段向上对齐的时候例外。 示例1:

CREATE SEQUENCE SQ_CSP_TABLENAME MINVALUE 1 START WITH 1 INCREMENT BY 1;

示例2:

IF c_CursorName%ISOPEN THEN CLOSE c_CursorName; END IF;

规则:缩进必须使用空格键,不允许使用TAB键。

规则:同一条语句占用多于一行时,每行的第一个关键字应当右对齐,但INSERT...SELECT语句例外。 示例1:

FETCH c_Cursor

INTO v_Field1, v_Field2, ... 2013-03-28

第8页,共71页

↑ 关键字右对齐

示例2:

SELECT FIELD1, FIELD2, ... FROM T_CSP_TABLENAME WHERE FIELD1 > 1

AND (FIELD2 < SYSDATE OR FIELD2 > SYSDATE + 3) AND FIELD3 LIKE 'HUAWEI%' GROUP BY FIELD1, FIELD2 ORDER BY FIELD1, FIELD2; ↑ 关键字右对齐

规则:在INSERT...SELECT语句中,如果需要换行时,应使INSERT INTO部分的字段与SELECT部分的字段一一对应,以增强可读性。 示例:

错误的写法:

BEGIN

INSERT INTO T_DEST_TABLENAME (DESTFIELDNAME1, DESTFIELDNAME2, DESTFIELDNAME3, DESTFIELDNAME4, DESTFIELDNAME5, DESTFIELDNAME6, DESTFIELDNAME7)

SELECT SRCFIELDNAME1, SRCFIELDNAME2, SRCFIELDNAME3, SRCFIELDNAME4, SRCFIELDNAME5, SRCFIELDNAME6, SRCFIELDNAME7 FROM T_SRC_TABLENAME; END;

正确的写法A:

BEGIN

INSERT INTO T_DEST_TABLE_NAME (DESTFIELDNAME1, DESTFIELDNAME2, DESTFIELDNAME3, DESTFIELDNAME4, DESTFIELDNAME5, DESTFIELDNAME6, DESTFIELDNAME7) SELECT SRCFIELDNAME1, SRCFIELDNAME2,

SRCFIELDNAME3, SRCFIELDNAME4, SRCFIELDNAME5, SRCFIELDNAME6, SRCFIELDNAME7 FROM T_SRC_TABLE_NAME; END;

正确的写法B:

BEGIN

INSERT INTO T_DEST_TABLE_NAME (DESTFIELDNAME1, -- 注释 2013-03-28

第9页,共71页

DESTFIELDNAME2, -- 注释 DESTFIELDNAME3, -- 注释 DESTFIELDNAME4, -- 注释 DESTFIELDNAME5, -- 注释 DESTFIELDNAME6, -- 注释 DESTFIELDNAME7) -- 注释 SELECT SRCFIELDNAME1, -- 注释 SRCFIELDNAME2, -- 注释 SRCFIELDNAME3, -- 注释 SRCFIELDNAME4, -- 注释 SRCFIELDNAME5, -- 注释 SRCFIELDNAME6, -- 注释 SRCFIELDNAME7 -- 注释 FROM T_SRC_TABLE_NAME; END;

正确的写法C:

BEGIN

INSERT INTO T_DEST_TABLE_NAME ( DESTFIELDNAME1, -- 注释 DESTFIELDNAME2, -- 注释 DESTFIELDNAME3, -- 注释 DESTFIELDNAME4, -- 注释 DESTFIELDNAME5, -- 注释 DESTFIELDNAME6, -- 注释 DESTFIELDNAME7) -- 注释 SELECT SRCFIELDNAME1, -- 注释 SRCFIELDNAME2, -- 注释 SRCFIELDNAME3, -- 注释 SRCFIELDNAME4, -- 注释 SRCFIELDNAME5, -- 注释 SRCFIELDNAME6, -- 注释 SRCFIELDNAME7 -- 注释 FROM T_SRC_TABLE_NAME; END;

正确的写法D:

BEGIN

INSERT INTO T_DEST_TABLE_NAME ( DESTFIELDNAME1, -- 注释 DESTFIELDNAME2, -- 注释 DESTFIELDNAME3, -- 注释 DESTFIELDNAME4, -- 注释 2013-03-28

第10页,共71页

DESTFIELDNAME5, -- 注释 DESTFIELDNAME6, -- 注释 DESTFIELDNAME7) -- 注释 SELECT SRCFIELDNAME1, -- 注释 SRCFIELDNAME2, -- 注释 SRCFIELDNAME3, -- 注释 SRCFIELDNAME4, -- 注释 SRCFIELDNAME5, -- 注释 SRCFIELDNAME6, -- 注释 SRCFIELDNAME7 -- 注释 FROM T_SRC_TABLE_NAME; END;

↑ 关键字右对齐

说明:

1、 在错误的写法中,虽然SELECT语句部分的SRCFIELDNAME1, SRCFIELDNAME2,

SRCFIELDNAME3可以写在一行中,但由于INSERT INTO语句部分中DESTFIELDNAME1, DESTFIELDNAME2写在一行中,而DESTFIELDNAME3在下一行,因此SELECT语句中每行的字段应与INSERT INTO语句中的字段一一对应(如正确的写法A);

2、 INSERT INTO语句中的各个字段折行后,应缩进并与上一字段左对齐(如正确的写法

B),或者与INTO关键字左对齐(如正确的写法C);

3、 SELECT语句中折行后的第一个字段名应缩进并与上一行的第一个字段名左对齐。

规则:INSERT INTO语句中,如果需要对每个字段增加注释,应将每个字段单独列为一行,并在行尾增加注释。 示例1:

INSERT INTO T_DEST_TABLE_NAME (DESTFIELDNAME1, -- 注释1 DESTFIELDNAME2, -- 注释2 DESTFIELDNAME3) -- 注释3 VALUES (FieldValue1, FieldValue2, FieldValue3);

或者

2013-03-28

第11页,共71页

INSERT INTO T_DEST_TABLE_NAME ( DESTFIELDNAME1, -- 注释1 DESTFIELDNAME2, -- 注释2 DESTFIELDNAME3) -- 注释3 VALUES (

FieldValue1, FieldValue2, FieldValue3);

或者

INSERT INTO T_DEST_TABLE_NAME (

DESTFIELDNAME1, -- 注释1 DESTFIELDNAME2, -- 注释2 DESTFIELDNAME3 -- 注释3 ) VALUES (

FieldValue1, FieldValue2, FieldValue3 );

其他说明:

1、 在规范的代码模板中详细给出了各种情况下的范例写法,请编码过程参考; 2、 在数据库脚本的编码过程中,请严格按照代码模板进行书写;

3、 对于模板中未涉及的情况,应在保证符合上述规范原则,同时和代码模板中的风格保

持一致的前提下,根据实际情况灵活处理。

3.3 空格及换行

规则:不允许把多个短语句写在一行中,即一行只写一条语句。 示例:

v_Variable1 := 1; v_Variable2 := 'abc';

应写成:

v_Variable1 := 1; v_Variable2 := 'abc';

2013-03-28 第12页,共71页

说明:两个赋值语句不能写在一行中,必须分两行写。

规则:相对独立的程序块之间、变量说明之后必须加空行。 示例:

v_Variable1 := 1;

IF v_BeginDate IS NULL THEN v_BeginDate := SYSDATE - 15; END IF;

应写成:

-- 初始化局部变量 v_Variable1 := 1;

-- 判断开始时间

IF v_BeginDate IS NULL THEN v_BeginDate := SYSDATE - 15; END IF;

说明:两个程序块在逻辑上相对独立,应用空行加以分隔,同时增加注释。

建议:建议对超过120字符的语句要分行书写,长表达式应在低优先级操作符处换行,操作符或关键字放在新行之首。划分出的新行应适当地缩进,使排版整齐、语句可读。是否分行应根据实际情况而定,原则是保证代码整齐、语句可读。 分行示例:

120字符 ↓

?? (a * b * c * d) + (e * f) + ??

应写成:

?? (a * b * c * d) + (e * f) + ??

说明:

1、 加法的优先级低于乘法,因此应在加号处换行;

2、 两组乘法虽然在逻辑上会先于加法执行,但显式加上括号使可读性更强。

规则:调用函数或过程时,如果参数列表超过120字符,应根据逻辑内容进行换行,或者每个参数占用一行。

2013-03-28

第13页,共71页

示例:

错误的写法:

120字符 ↓

P_PROCEDURE(i_Param1, i_Param2, i_Param3, o_Param1, oParam2, ...);

正确的写法A:

P_PROCEDURE(i_Param1, i_Param2, i_Param3, o_Param1, o_Param2, ...);

正确的写法B:

P_PROCEDURE(i_Param1, -- 注释 i_Param2, -- 注释 i_Param3, -- 注释 o_Param1, -- 注释 o_Param2, -- 注释 ...) -- 注释

说明:

1、 因为前三个为输入参数,后两个为输出参数,因此在第3、4参数之间换行比较清晰

(如正确的写法A);

2、 有时为了增加注释,可以使每个参数皆占用一行(如正确的写法B); 3、 参数换行以后与上一行的第一个参数对齐。

规则:双目运算符、操作符前后应以空格分隔,间隔符之后应以空格分隔。 示例:

v_DateVar:=TO_DATE('2001-01-01 01:30:00','YYYY-MM-DD HH24:MI:SS');

v_IntegerVar1:=v_IntegerVar2+v_IntegerVar3;

IF v_Number>0 THEN

应写成:

v_DateVar := TO_DATE('2001-01-01 01:30:00', 'YYYY-MM-DD HH24:MI:SS'); ↑ ↑ 赋值符前后加空格 逗号后面加空格

v_IntegerVar1 := v_IntegerVar2 + v_IntegerVar3; ↑ ↑ 赋值符前后加空格 加号前后加空格 2013-03-28

第14页,共71页

IF v_Number > 0 THEN ↑ 比较符号前后加空格

建议:不同优先级的操作符混合使用时,建议使用括号进行隔离。 示例:

?? a * b + c ??

应写成:

?? (a * b) + c ??

说明:使用括号使代码的优先级更加清晰,而且可以避免犯错。

建议:SQL语句中存在不同优先级的关系运算符时,建议使用括号。 示例:

WHERE FIELD1 > 1 AND FIELD2 < SYSDATE OR FIELD3 > SYSDATE + 3

应写成:

WHERE (FIELD1 > 1 AND FIELD2 < SYSDATE) OR (FIELD3 > SYSDATE + 3)

说明:如果SQL语句的条件复杂,很容易出现问题,因此增加括号可以提高可阅读性。

3.4 创建表

规则:脚本中的字段名缩进为4个空格。

规则:脚本中字段名称、字段类型、DEFAULT关键字应左对齐,NULL/NOT NULL应右对齐(也可以认为就是NULL关键字左对齐)。 示例:

CREATE TABLE T_WF_TABLE_NAME (

INTFIELD DATEFIELD )

TABLESPACE SERVICE_MAIN_DAT;

INT

NOT NULL, NOT NULL, NULL, NULL

FLOATFIELD NUMBER(4, 2)

DATE

VARCHAR2FIELD

DEFAULT 1.23

DEFAULT SYSDATE

VARCHAR2(200)

说明:至于每行中的每个项目之间使用多少个空格没有明确要求,只要求从纵向上各个字

2013-03-28

第15页,共71页

段的名称、数据类型、缺省值、是否为空等对齐美观即可。

3.5 创建过程/函数/包

规则:脚本中的参数缩进为4个空格。

规则:脚本中的参数名称、数据类型、注释信息应左对齐,IN/OUT/IN OUT关键字左对齐右对齐皆可。 示例:

CREATE OR REPLACE PROCEDURE P_CSP_PROCEDURENAME (

i_DateParam o_IntParam o_RetCode )

DATE,

-- 注释 -- 注释 -- 注释

IN OUT INT, OUT INT

o_VarcharParam OUT VARCHAR2, -- 注释

或者

CREATE OR REPLACE PROCEDURE P_CSP_PROCEDURENAME (

i_DateParam o_IntParam o_RetCode )

DATE, INT, INT

-- 注释 -- 注释 -- 注释

IN OUT

OUT OUT

o_VarcharParam VARCHAR2, -- 注释

说明:至于每行中的每个项目之间使用多少个空格没有明确要求,只要求从纵向上各个参数的名称、数据类型、IN/OUT关键字等对齐美观即可。

2013-03-28 第16页,共71页

第4章 命名规范

规则:所有用户自定义的数据库对象名称统一使用形如“对象前缀+下划线+模块名缩写+下划线+对象名称”的格式。 说明:

? 对象名称中可以根据需要使用下划线进行分隔;

? 创建对象时,禁止通过双引号指定对象名称,ORACLE在数据字典中统一存放为

大写;

? 对象类型前缀建议不要超过三个字符,可参考以下对象前缀表;

? 编码时禁止以ORACLE系统对象的前缀作为对象类型前缀,具体请参考

ORACLE系统对象使用前缀表;

? 模块名缩写建议不要超过三个字符,可参考附录中的常见模块名缩写表; ? 数据表字段名称没有前缀; ? 对象名称长度不宜超过18个字符。 ? 计费相关模块名:Comm,Cash,Owe,Acct

表2

对象类型 前缀 对象前缀表

示例 TBS_ACCT_INDEX TBS_COMM_INDEX T_OWE_TABLENAME T_CASH_BEGINDATE 备注 TBS 表空间命名(TableSpace) 表(Table) T 遵循现有规则,以A开头,例如:A_OWE_ITEM 建议采用 STATE_DATE的方式来命名 视图(View) 字段(Field) V 无 V_OWE_VIEWNAME FIELDNAME STATE_DATE 序列(Sequence) SEQ SEQ_TABLENAME_FIELDNAME 2013-03-28 第17页,共71页

索引(Index) IDX IDX_OWE_INDEXNAME IDX_CASH_INDEXNAME 如果表名或字段名过长,则用表名和字段名的缩写表示 如果表名或字段名过长,则用表名和字段名的缩写表示 如果表名过长,则用表名的缩写表示 T1为外键所在的表,T2为外键所参照的表 如果表名过长,则用表名的缩写表示 唯一索引 UK UK_OWE_INDEXNAME UK_CASH_INDEXNAME 主键(Primary Key) 外键(Foreign Key) PK PK_OWE_KEYNAME PK_CASH_KEYNAME FK_OWE_T1_T2 FK_CASH_T1_T2 FK 簇(Cluster) CLS CLS_OWE_TABLENAME CLS_CASH_TABLENAME 触发器(Trigger) 过程(Stored Procedure) 函数(Function) 包(Package) TRG TRG_OWE_TRIGGERNAME TRG_CASH_TRIGGERNAME P_OWE_PROCEDURENAME P_CASH_PROCEDURENAME P_OWE_FUNCTIONNAME P_CASH_FUNCTIONNAME PKG_OWE_PKGNAME PKG_CASH_PKGNAME SYN_OWE_TABLENAME P F PKG 同义词(Synonyms) 保存点(SavePoint) 类型(Type)

SYN SPT TYP SPT_OWE_SPTNAME SPT_CASH_SPTNAME TYP_OWE_TYPENAME 表3

对象类型 簇(Cluster) 索引(Index) ORACLE系统对象使用前缀表

前缀 C_ AQ$_ HS$_

示例 C_USER# AQ$_MSGTYPE_PRIMARY HS$_GRANTUSER_PK 第18页,共71页

2013-03-28

I_ SYS_ 包(Package) DBMS_ UTL_ AQ$_ EVT_ HS$_ ORA_ REPCAT$_ SMP_ SYSTEM_ DEF$_ SMP_ AQ$_ HS$_ DEF$_ EVT_ REPCAT$_ SMP_ AQ$_ SMP_ I_AUDIT SYS_C00512 DBMS_OUTPUT UTL_FILE AQ$_QIDSEQ EVT_NOTIFY_SEQ HS$_CLASS_CAPS_S ORA_TQ_BASE# REPCAT$_REPPROP_KEY SMP_LONG_ID SYSTEM_GRANT DEF$_ERROR SMP_JOB_ID AQ$_MESSAGE_TYPES HS$_PRIVILEGES DEF$_LOB EVT_OPERATORS REPCAT$_DDL SMP_JOB AQ$_DEF$_AQCALL SMP_BLOB 序列(Sequence) 同义词(Synonyms) 表(Table) 视图(View)

规则:所有用户定义的存储过程或函数中使用的参数、变量、异常等统一采用“小写前缀+下划线+逻辑首字母大写”的格式,其中的小写前缀代表参数、变量、类型或异常等的类型,而常量则统一使用全部大写(可根据情况使用下划线进行分隔)。小写前缀请参考下表:

表4

变量类型 函数、过程输入参数 函数、过程输出、输入输出参数 函数、过程局部变量 游标变量 i o v _Cursor 参数、变量、常量、异常等前缀表

示例 i_BeginDate i_EndDate o_Result o_Info v_WorkerNo CursorName_Cursor 备注 首字母 2013-03-28 第19页,共71页

自定义常量 自定义异常 自定义表类型 自定义表变量 自定义记录类型 自定义记录变量

c e _Table_Type _Table c_BeginTime e_UserException Emp_Table_Type Emp_Table _Record_Type Emp_Record_Type _Record Emp_Record 规则:标识符的命名要清晰、明了,有明确含义,同时使用完整的单词或大家基本可以理解的缩写,避免使人产生误解。

建议:较短的单词可通过去掉“元音”形成缩写;较长的单词可取单词的头几个字母形成缩写;一些单词有大家公认的缩写,请参考附录中的常用词缩写表。

规则:命名中若使用特殊约定或缩写,则要有注释说明。

说明:应该在源文件的开始之处,对文件中所使用的缩写或约定,特别是特殊的缩写,进行必要的注释说明。

规则:所有的命名不允许使用拼音,必须使用英文命名。

规则:使用有意义、易于记忆、描述性强、简短及具有唯一性的英文单词。使用下划线要有一致性,要么不用。自己特有的命名风格,要自始至终保持一致,不可来回变化。 说明:个人的命名风格,在符合所在项目组或产品组的命名规则的前提下,才可使用。(即命名规则中没有规定到的地方才可有个人命名风格)。

规则:对于变量命名,禁止取单个字符(如i、j、k...),建议除了要有具体含义外,还能表明其变量类型、数据类型等。形如i、j、k的变量只允许作为局部循环变量。

说明:变量,尤其是局部变量,如果用单个字符表示,很容易敲错(如i写成j),而编译时又检查不出来,有可能为了这个小小的错误而花费大量的查错时间。

2013-03-28

第20页,共71页

规则:除非必要,不允许使用数字或较奇怪的字符来定义标识符。 示例:

如下命名,使人产生疑惑。

DECLARE temp_0_TEST VARCHAR2(10);

规则:用正确的反义词组命名具有互斥意义的变量或相反动作的函数等。 示例:

Start <-> Finish First <-> Last Prior <-> Next Add <-> Remove Get <-> Set

启动 <-> 完成 第一个 <-> 最后一个 前一个 <-> 后一个 增加 <-> 删除 创建 <-> 析构 获取 <-> 设置 增量 <-> 减量 加锁 <-> 解锁 打开 <-> 关闭

Create <-> Destroy

Increment <-> Decrement Lock <-> UnLock Open <-> Close

2013-03-28 第21页,共71页

第5章 注释规范

建议:存储过程/函数脚本代码有效注释量应该在20%以上。

说明:注释的原则是有助于对程序的阅读理解,在该加的地方都加了,注释不宜太多也不能太少,注释语言必须准确、易懂、简洁。

规则:在数据库脚本文件头部应进行注释,注释必须列出:版权说明、版本号、生成日期、作者、内容、功能、与其它文件的关系、修改日志等,头文件的注释中还应有函数或过程功能简要说明。 示例:

------------------------------------------------------------------------- -- File Name -- Author -- Version -- Date -- Copyright -- Usage -- Comments -- History -- 1. Date -- Author -- 2. ......

-------------------------------------------------------------------------

: 该脚本文件的文件名 : 该脚本文件的作者姓名与工号 : 该脚本文件的版本号 : 该脚本文件的最后更新日期 : 该脚本文件的版权信息

: 简要描述该脚本的使用/加载方法 : 该脚本文件的注释信息 : 该脚本文件的维护历史信息

: 修改日期,格式为YYYY-MM-DD : 修改人姓名与工号

-- Description : 该脚本文件的描述信息

-- Function List : 该脚本文件提供对象、函数、过程的列表

-- Modification : 修改说明

说明:格式内容请参见代码模板文件头。

规则:函数/存储过程头部应进行注释,列出:功能说明、设计人、编码人、创建日期、修改记录、调用关系(可选)等,输入参数/输出参数/返回值的说明直接添加到参数后面。 示例:

CREATE OR REPLACE FUNCTION F_CSP_FUNCTIONNAME /*

Description : 该函数的功能说明 Author 2013-03-28

: 姓名 工号

第22页,共71页

Date Version Caller Callee Comments History 1. Date */ (

i_DateParam o_IntParam ) RETURN INT AS

DATE,

-- 输入参数注释。包括含义、值域等。 -- 输出参数描述。 -- 返回值。

Author

: YYYY-MM-DD : 版本 : 调用者 : 被调用者

: 注释信息(包括产生异常的说明) :

: 修改日期,格式为YYYY-MM-DD : 修改人姓名与工号

Modification : 修改说明

2. ......

IN OUT VARCHAR2, -- 输入输出参数注释。

o_FloatParam OUT INT

规则:边写代码边注释,修改代码同时修改相应的注释,以保证注释与代码的一致性。不再有用的注释要删除。

规则:注释的内容要清楚、明了,含义准确,防止注释二义性。 说明:错误的注释不但无益反而有害。

规则:避免在注释中使用缩写,特别是非常用缩写。 说明:在使用缩写时或之前,应对缩写进行必要的说明。

规则:单行注释符“--”后必须加上一个空格。

规则:注释应与其描述的代码相近,对代码的注释应放在其上方或右方(对单条语句的注释)相邻位置,不可放在下面,如放于上方则需与其上面的代码用空行隔开。 示例:

BEGIN ??

-- i_DateParam必须早于当前时间 2013-03-28

第23页,共71页

IF i_DateParam >= SYSDATE THEN RETURN 1; END IF; ?? END;

规则:注释与所描述内容进行同样的缩进。

说明:可使程序排版整齐,并方便注释的阅读与理解。

规则:注释与其上的代码用空行隔开。

建议:对变量的定义和分支语句(条件分支、循环语句等)建议给出注释。

说明:这些语句往往是程序实现某一特定功能的关键,对于维护人员来说,良好的注释帮助更好的理解程序,有时甚至优于看设计文档。

规则:不允许在一行代码或表达式的中间插入注释。

说明:不应在代码或表达中间插入注释,否则容易使代码可理解性变差。

规则:通过对函数或过程、变量、结构等合适的命名以及合理地组织代码的结构,使代码成为自注释的。

说明:清晰准确的函数、变量等的命名,可增加代码可读性,并减少不必要的注释。

规则:在代码的功能、意图层次上进行注释,提供有用、额外的信息。

说明:注释的目的是解释代码的目的、功能和采用的方法,提供代码以外的信息,帮助读者理解代码,防止没必要的重复注释信息。 示例:

如下注释意义不大

-- i_RetCode = 0 IF i_RetCode = 0 THEN

2013-03-28 第24页,共71页

而如下的注释则给出了额外有用的信息。

-- 流程传入的标志为发送成功 IF i_RetCode = 0 THEN

2013-03-28

第25页,共71页

第6章 常用语法

6.1 变量声明

规则:代码中声明与表的字段相对应的变量时,应保证变量名和字段名相同。 说明:这样要求的目的是增强可读性。 示例:

DECLARE

v_DateField T_TABLENAME.DATEFIELD%TYPE; BEGIN

SELECT DATEFIELD INTO v_DateField FROM T_TABLENAME WHERE ROWNUM = 1; END;

规则:代码中声明与表的字段相对应的变量时,对类型的定义需要使用%TYPE方式。 说明:这样表结构的变动不会影响存储过程,避免表结构变更后出现变量长度或类型不一致的问题。

6.2 返回值

规则:函数的返回值定义应遵从下列规范:成功出口返回0,失败出口返回大于0整数。过程中定义的用于返回错误码的OUTPUT参数,其定义应遵从下列规范:成功出口返回0,失败出口返回非0整数。

6.3 符号*

规则:脚本中不允许出现“*”的用法,必须用实际的字段名代替,INSERT语句必须指定要插入的字段名。 示例:

1、游标定义

2013-03-28

第26页,共71页

错误用法:

CURSOR c_CursorName IS SELECT * FROM TABLENAME ...

正确用法:

CURSOR c_CursorName IS

SELECT FIELD1, FIELD2, ... FROM TABLENAME ...

2、INSERT 语句 错误用法:

INSERT INTO TABLENAME VALUES ...

正确用法:

INSERT INTO TABLENAME (FIELD1, FIELD2, ...) VALUES ...

6.4 包的使用

建议:ORACLE的包类似C++中的Class,有包头和包体两部分组成;包能够把相关的功能封装性在一个包中,包里面里可以有函数和过程。PACKAGE与PROCEDURE和FUNCTION的优点是封装性比较好;在开发过程中,可以把功能点紧密相关的PROCEDURE、FUNCTION封装在一个包里面。在对包体进行编译时,调用该包的存储过程不会失效。

6.5 绑定变量

规则:使用绑定变量的SQL语句,能使用绑定变量方式的业务逻辑下不允许使用绑定常量实现。

说明:在存储过程拼SQL语句作为动态SQL执行时,尤其需要注意。 示例:

错误用法:

v_SQL := 'DELETE FROM TABLENAME WHERE FIELD1 > SYSDATE AND FIELD2 = 102'; EXECUTE IMMEDIATE v_SQL;

正确用法:

v_ID := 102; 2013-03-28

第27页,共71页

v_SQL := 'DELETE FROM TABLENAME WHERE FIELD1 > :1 AND FIELD2 = :2'; EXECUTE IMMEDIATE v_SQL USING SYSDATE, v_ID;

规则:为提升性能,减少循环的开销,可以使用批量绑定。

说明:下面示例中的UPDATE语句可以一次将多条记录进行更新,而避免了通过使用循环同一条SQL执行多次。 示例:

CREATE OR REPLACE PROCEDURE P_CSP_TEST /*

Description : 根据输入的多个工单流水号,更新对应的SERVICECLASSID值 Author Date Version Caller Callee Comments History 1. Date */ (

i_SerialNos VARCHAR2, -- 一次输入多个工单流水号以'~'分隔' i_ServiceClassID VARCHAR2,

o_Ret OUT VARCHAR2 -- 成功返回0,失败返回1 ) AS

TYPE typ_StrArray IS TABLE OF VARCHAR2(500) INDEX BY BINARY_INTEGER; v_ArrSerial typ_StrArray; BEGIN

FOR i IN 1..9999 LOOP

-- 把输入参数的值取出存放在数组v_ArrSerial中

EXIT WHEN GetParamStr(i_SerialNos, '~', i, v_ArrSerial(i)) <> 0;

END LOOP;

-- 根据数组中的工单流水号批量更新 FORALL i IN 1..v_ArrSerial.COUNT 2013-03-28

第28页,共71页

Author

: 姓名 工号 : YYYY-MM-DD : 版本 : 调用者 : 被调用者 : 注释信息 :

: 修改日期,格式为YYYY-MM-DD : 修改人姓名与工号

Modification : 修改说明

2. ......

UPDATE T_WF_SERVICEINFO t

SET t.SERVICECLASSID = i_ServiceClassID WHERE SerialNo = v_ArrSerial(i);

COMMIT;

o_Ret := 0;

EXCEPTION

WHEN OTHERS THEN ROLLBACK; o_Ret := 1; END;

6.6 异常处理

规则:函数/过程中应该有异常处理的代码,除非需要将任何可能的异常都向上抛出。 说明:不论代码逻辑是否简单,只要有可能会抛出异常,函数/过程块就应该包括异常处理代码。详见代码模板。

规则:如果需要的话,可以在异常处理部分将异常继续向上抛出给调用者。

说明:如果有些异常是预料可能产生,而且脚本需要根据是否有异常来做不同的逻辑处理,这种情况可以在异常处理部分将该异常进行处理,但可能有些意料之外的异常,需要继续向上抛出,便于调用者了解脚本执行是否成功,以便于调用者作下一步的处理如写错误日志等操作。

规则:如果需要自定义异常,必须在异常处理块中对其进行处理。

说明:如果自定义了异常,却没有相应的代码进行处理,那么就应该去掉该异常的定义。

规则:在对容错性要求比较高的情况下,对异常块中的代码还需要判断是否可能触发异常,必要的时候应使用嵌套的异常。

说明:在异常处理部分中的写日志之前,如果有事务,一定要先ROLLBACK;异常块中写日志、向表中插入一条初始化记录等语句也可能失败,对这些代码必要时也应该增加异

2013-03-28

第29页,共71页

常保护,即使用嵌套的异常处理。

6.7 事务控制

规则:在任何出口之前,只要存在事务未结束,必须提交或者回滚,除非有特殊设计考虑。

说明:存储过程在每个出口前,如果启动了事务必须结束所有事务,以提交(COMMIT)或回滚(ROLLBACK)来结束事务,否则可能会导致表锁等严重问题;如果在存储过程中,没有启动事务,就不必执行COMMIT或ROLLBACK,否则多余的ROLLBACK或COMMIT操作将增加数据库的额外开销。

规则:ORACLE的事务是串行的,嵌套调用中内层存储过程的提交会导致外层的存储过程事务被一并提交;诸如生成流水号这类存储过程应使用独立事务,否则在产生流水号时就将之前的业务逻辑操作提交,而后续的操作不能保证在一个事务中。例如现有系统中一个工单循环派给多个部门时,循环体内产生流水号,如最后一个派单失败时回滚操作根本就不能回撤所有操作,导致事务一致性被破坏。

建议:尽量分解大事务,事务的大小应视系统的性能和应用的具体情况而定,过多过小的事务造成重做日志同步的等待,比如要往一个表插入100万条记录,如果每条记录提交一次,则事务太小,可以做一个计数器,设置1万或事务5万条作一次提交。

6.8 游标使用

规则:原则上避免使用游标,尤其是动态游标。 说明:

1. 游标的效率较低,如果在代码中可以通过不同的条件分支实现的逻辑,尽量不要使用

游标。

2. 动态游标通常都可以转化为若干个静态游标,因此除非必要,尽量使用静态游标代替

动态游标。

2013-03-28

第30页,共71页

建议:推荐使用CURSOR FOR LOOP语句,可以隐式打开关闭游标;否则,显式打开游标,就必须在任何出口之前显式关闭游标。下面的示例通过 FOR IN LOOP取数据,不需要显示打开和关闭游标。 示例:

DECALRE

CURSOR c_Dept IS SELECT DEPTNO, DNAME FROM DEPT ORDER BY DEPTNO; v_Tot_Salary EMP.SALARY%TYPE; BEGIN

FOR r_Dept IN c_Dept LOOP

DBMS_OUTPUT.PUT_LINE('Department:' || r_Dept.DEPTNO); v_Tot_Salary := 0; END LOOP; END;

规则:如果存储过程返回游标类型参数,必须在任何出口前打开游标。

说明:如果存储过程有游标类型的输出参数,而在某个分支中未打开,其调用者使用该游标获取数据时会报错。 示例:

CREATE OR REPLACE PROCEDURE P_TMP_TESTSYSCURSOR( o_Cur OUT SYS_REFCURSOR -- 注释 ) AS BEGIN

IF v_Flag > 0 THEN

OPEN o_Cur FOR SELECT FIELD1 FROM T_WF_TABLE; RETURN; ELSE RETURN; END IF; END;

应写成:

CREATE OR REPLACE PROCEDURE P_TMP_TESTSYSCURSOR( o_Cur OUT SYS_REFCURSOR -- 注释 ) AS BEGIN

IF v_Flag > 0 THEN 2013-03-28

第31页,共71页

OPEN o_Cur FOR SELECT 0 AS RET, FIELD1 AS MSG FROM T_WF_TABLE; RETURN; ELSE

OPEN o_Cur FOR SELECT -1 AS RET, ’ErrorMsg’ AS MSG FROM DUAL; RETURN; END IF; END;

6.9 代码规模

建议:建议每个存储过程和函数的规模不宜超过500行。

说明:存储过程和函数的逻辑不宜太过复杂,应当注意对于同样的计算,存储过程执行效率远低于其他应用程序,所以要避免将大量业务逻辑都放到存储过程实现。

2013-03-28 第32页,共71页

第7章 SQL建议与约束

7.1 建议

建议:在开发过程中,在SQL语句中,尽量不要指定索引。

说明:指定索引后,在以后的优化过程中,无法通过创建和优化索引,使对应的SQL语句用到其他更好的索引,对指定的索引删除、重建改名后,可能导致该SQL语句用不到索引。

建议:在不使用DISTINCT、UNION、ORDER BY、GROUP BY情况下,也能实现业务功能的情况,一定不要使用这些功能。使用这些功能会导致对应的SQL语句排序,增加系统的开销。 示例:

错误的用法:

SELECT COUNT(*) FROM (

SELECT SERIALNO

FROM T_PUB_COMMONINFO WHERE A.PARTID >= '0127' AND A.PARTID <= '1227'

ORDER BY ACCEPTBEGINTIME DESC -- 没有用的ORDER BY )

建议:创建组合索引时,要注意组合索引的顺序和字段的选择性,把经常出现在WHERE条件中同时选择性比较好的字段放在复合索引的第一个位置。

说明:SQL语句在使用复合索引时,与该复合索引字段的组合顺序有关,当索引的第一个字段出现在WHERE条件中,这时候对该表的查询能够用到该索引,当该索引的第一个字段没有出现在SQL语句的查询条件中,但该索引的其他的字段出现在WHERE条件中时,在基于规则的优化模式中,SQL引擎会用全表扫描方式查询,在基于成本的优化模式中的(First Rows)方式查询,SQL引擎会对该索引全索引扫描方式查询。 示例:

2013-03-28 第33页,共71页

错误的用法:

ALTER TABLE T_WF_SERVICEINFOHIS

ADD CONSTRAINT PK_WF_SERVICEINFOHIS PRIMARY KEY (MONTHDAY, SERIALNO, SERVICECLASSID);

说明:在业务逻辑的查询中,许多时候之间按SERIALNO, SERVICECLASSID查时,在基于规则的优化模式中,用不到索引。

正确的用法:

ALTER TABLE T_WF_SERVICEINFOHIS

ADD CONSTRAINT PK_WF_SERVICEINFOHIS PRIMARY KEY (SERIALNO, SERVICECLASSID, MONTHDAY);

建议:创建表时数据和索引建议在不同的表空间。

建议:在WHERE条件表达式中,尽可能避免在要使用到索引的字段上使用函数,如果要使用函数建议创建相应的函数索引。 示例:

错误用法:

SELECT FIELD FROM TABLENAME

WHERE SUBSTRB(FIELD, 1, 4) = '5378'

正确用法:

SELECT FIELD FROM TABLENAME

WHERE FIELD LIKE '5378%'

建议:当查询条件选择性很低时使用索引反而降低效率,这种情况下,应该用特殊的方法屏蔽该索引,如果字段为数值型的就在表达式的字段名后+ 0,为字符型的就并上空串。 示例:

SELECT NUM_FIELD FROM TABLENAME

WHERE NUM_FIELD + 0 > 30

SELECT STRING_FIELD FROM TABLENAME

WHERE STRING_FIELD || '' = 'EXAMPLE' 2013-03-28

第34页,共71页

建议:在SQL语句中,尽可能使用变量绑定,少用常量绑定。

建议:如果业务逻辑允许的情况下,尽量用UNION ALL代替UNION,用UNION ALL代替OR。 示例:

错误的用法:

SELECT SERIALNO

FROM T_WF_DISPOSALSTATUSHIS

WHERE (ACCEPTPHONE = :B4 OR CALLERNO = :B3 OR USERPHONE1 = :B2) AND ACCEPTTIME > SYSDATE - :B1

正确的用法:

SELECT SERIALNO

FROM T_WF_DISPOSALSTATUSHIS WHERE (ACCEPTPHONE = :B4)

AND ACCEPTTIME > SYSDATE - :B1 UNION ALL SELECT SERIALNO

FROM T_WF_DISPOSALSTATUSHIS WHERE (CALLERNO = :B3)

AND ACCEPTTIME > SYSDATE - :B1 UNION ALL SELECT SERIALNO

FROM T_WF_DISPOSALSTATUSHIS A WHERE (USERPHONE1 = :B2)

AND ACCEPTTIME > SYSDATE - :B1

建议:如果要对整个表或分区的数据删除,建议使用TRUNCATE替代DELETE。

建议:为了提高系统的并发性,尽可能的使事务的时间缩短。

建议:创建分区表的索引时,必须创建本地(LOCAL)索引。

说明:如果创建的是全局索引,在对分区表的某个分区TRUNCATE时,导致该索引失效;需要对该全局索引进行重新编译。

2013-03-28

第35页,共71页

建议:避免通过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页

本文来源:https://www.bwwdw.com/article/m756.html

Top