一. 对象命令规则
1.1 数据文件
如果数据库采用文件系统,而不是裸设备,约定下列命名规则:
1) 数据文件以表空间名为开始,以.dbf为结尾,全部采用小写英文字母加数字命名。如该表空间有多个数据文件,则从第2个数据文件开始,。
例:对system表空间的数据文件:system.dbf,system02.dbf
2) 对oracle数据库的控制文件,用control.ctl来表示。如:control01.ctl,control02.ctl。
3) 对oracle数据库的日志文件,在线日志文件用redo<组名><文件序列名>.log来表示。如第一组的两个文件表示为redo11.dbf和redo12.dbf。
4) 归档日志用arch_%t_%s.arc来表示。其中%t和%s均为oracle约定的变量。
1.2 表空间
1.2.1 数据库系统表空间
数据库系统表空间包括system表空间,临时表空间,回滚段的表空间。约定下列命名规则:
1) system表空间由数据库系统表空间,一般只有一个数据文件。
2) 临时表空间用temp来表示。 有多个在后面加数字, 如:temp02.dbf
3) 回滚段表空间用undotbs来表示。如果有多个回滚段表空间,undotbs02.dbf
1.2.2 数据库的用户表空间
数据库的用户表空间用ts_<表空间名>来表示。其中,表空间名分为:
1) 数据空间:对于用户的缺省表空间,用default来表示。对于其他的表空间,根据存放在表空间上的表的类别来表示。如放代码的表,用code来表示。放客户资料的表,用customer来表示。尽量用一个表空间来存放该类的表。如果某表特别大,可考虑单独使用一个表空间。
2) 索引空间:在相应的数据表空间的名字前加ind_。如对用户缺省表空间的索引空间,用ts_ind_default来表示。对代码表的索引表空间,用ts_ind_code来表示。
1.3 表
1.3.1 数据库表的命名规则:
1) 表名一般用T_开头,对于系统表,用SYS_开头,数据表用DAT_开头,日志表用LOG_开头,配置表用CFG_开头。表名长度不能超过30个字符,表名中含有单词全部采用单数形式,单词要大写。
2) 多个单词间用下划线(_)进行连接。若库中有多个系统,表名采用系统名称+单词或多个单词,系统名是开发系统的缩写,如VNET。
3) 表中含有的单词建议用完整的单词。如果导致表名长度超过30个字符,则从最后一个单词开始,依次向前采用该单词的缩写。如果没有约定的缩写,则采用该单词前4个字母来表示。
1.3.2 数据库表的字段命名规则:
1)数据库字段名全部采用小写英文单词,单词之间用”_”隔开。字段长度不能超过30个字符。
2)如果该字段是代码,则在单词后加_id。
3)如果该字段表示的是时间,则使用_time为后缀。
1.4 视图
数据库视图的命名规则:
1)视图名用V_开头,视图名长度不能超过30个字符。视图名用大写的英文单词来表示。
2)视图由几个表产生就用下划线(_)连接几个表的名,如果表过多可以将表名适当简化,但一定要列出所有表名。
1.5 序列
数据库序列的命名规则:
序列名用seq_开头,后面跟使用该序列的字段名。如果有几个字段用同一个序列,用下划线(_)连接几个字段的名称。如果不同表中相同的字段名需要使用不同的序列,则在字段名后加表的特征,用下划线(_)连接。序列名长度不能超过30个字符。序列名用小写的英文单词来表示。
1.6 存储过程
存储过程的命名采用如下规则:
存储过程名用Proc_开头,存储过程名长度不能超过30个字符。存储过程名用小写的英文单词来表示。
1.7 函数
函数的命名采用如下规则:
函数名用Fu_开头,函数名长度不能超过30个字符。函数名用小写的英文单词来表示。
1.8 触发器
触发器的命名规则:
触发器名用Trg_开头,触发器名长度不能超过30个字符。触发器名用小写的英文单词来表示。
1.9 主键
主键的命名规则:
主键名用pk_开头,后面跟该主键所在的表名。主键名长度不能超过30个字符。如果过长,可对表名进行缩写。缩写规则同表名的缩写规则。主键名用小写的英文单词来表示。
1.10 外键
外键的命名规则:
外键名用fk_开头,后面跟该外键所在的表名和对应的主表名(不含t_)。子表名和父表名自己用下划线(_)分隔。外键名长度不能超过30个字符。如果过长,可对表名进行缩写。缩写规则同表名的缩写规则。外键名用小写的英文单词来表示。
1.11 索引
索引的命名规则:
1)索引名用小写的英文字母和数字表示。索引名的长度不能超过30个字符。
2)主键对应的索引和主键同名。
3)每类索引都用_结束。
4)唯一性索引用uni_开头,后面跟表名。一般性索引用ind_开头,后面跟表名。
5)如果索引长度过长,可对表名进行缩写。缩写规则同表名的缩写规则。
1.12变量
1) 定义变量时以v_作为前缀,如v_sal
2) 定义常量时以c_作为前缀,如c_rate
3) 定义游标时,建议使用_cursor作为后缀,如emp_cursor
4) 定义异常时,以e_作为前缀,如e_integrity_error
5) 定义PL/SQL表类型时,使用_table_type作为后缀,如sal_table_type.
6) 定义表变量时,以_table作为后缀,如sal_table
7) 同样,定义PL/SQL记录型时以_record_type作为后缀
8) 定义PL/SQL记录变量时以_record作为后缀
二. SQL编写规范
2.1 关键字大小写
(1)SQL关键词大写.
如SELECT,UPDATE,FROM,ORDER,BY,DECLARE,BEGIN,END等。
(2)数据类型也采用大写,比如VARCHA2。
(3)标识符和参数采用小写,如v_sal。
(4)数据库对象和列以及别名用小写。
2.2 一些SQL 优化事项
2.2.1 使用索引
建索引时,默认是B-tree索引。 B树索引保存了在索引列上有值的每个数据行的ROWID值。用索引查询时,先从索引查询,如果匹配到了相关记录,则通过rowid去读相应的记录。 所以对于返回结果集小于全表记录的30%时,走索引能节省很多时间。 当返回结果集较多时,建议走全表扫描。
索引需要空间来存储,也需要定期维护, 每当有记录在表中增减或索引列被修改时, 索引本身也会被修改. 这意味着每条记录的INSERT , DELETE , UPDATE将为此多付出4 , 5 次的磁盘I/O . 因为索引需要额外的存储空间和处理,那些不必要的索引反而会使查询反应时间变慢。定期的重构索引是有必要的.:
ALTER INDEX <INDEXNAME> REBUILD <TABLESPACENAME>
这块可以参考我的Blog:
Oracle 索引的维护
http://blog.csdn.net/tianlesoftware/archive/2010/06/19/5680706.aspx
2.2.2 索引限制
SQL语句的好坏,决定是否使用索引,在以下4种情况下,即使表上有索引,也不走索引。
(1)使用不等于操作符(<>、!=)
这里可以把条件改成> and <,就可以使用索引了。
(2)使用IS NULL 或IS NOT NULL
使用IS NULL 或IS NOT NULL同样会限制索引的使用。因为NULL值并没有被定义。在SQL语句中使用NULL会有很多的麻烦。因此建议开发人员在建表时,把需要索引的列设成 NOT NULL。如果被索引的列在某些行中存在NULL值,就不会使用这个索引,除非索引是一个位图索引。
(3)使用函数
如果不使用基于函数的索引,那么在SQL语句的WHERE子句中对存在索引的列使用函数时,会使优化器忽略掉这些索引。
(4)比较不匹配的数据类型
不同类型之间的比较也会限制索引。这种情况可以在比较之前做一次类型转换,如:to_number(account_number)=990354
不匹配的数据类型之间比较会让Oracle自动限制索引的使用,即便对这个查询执行Explain Plan也不能让您明白为什么做了一次“全表扫描”。
2.2.3 选择最有效率的表名顺序(只在基于规则的优化器中有效)
ORACLE 的解析器按照从右到左的顺序处理FROM子句中的表名,FROM子句中写在最后的表(基础表 driving table)将被最先处理,在FROM子句中包含多个表的情况下,必须选择记录条数最少的表作为基础表。如果有3个以上的表连接查询, 那就需要选择交叉表(intersection table)作为基础表, 交叉表是指那个被其他表所引用的表.
2.2.4 WHERE子句中的连接顺序
ORACLE采用自下而上的顺序解析WHERE子句,根据这个原理,表之间的连接必须写在其他WHERE条件之前, 那些可以过滤掉最大数量记录的条件必须写在WHERE子句的末尾.
2.2.5 SELECT子句中避免使用 *
ORACLE在解析的过程中, 会将'*' 依次转换成所有的列名, 这个工作是通过查询数据字典完成的, 这意味着将耗费更多的时间.
2.2.6 减少访问数据库的次数
ORACLE在内部执行了许多工作: 解析SQL语句, 估算索引的利用率, 绑定变量 , 读数据块等;
2.2.7 使用DECODE函数来减少处理时间
使用DECODE函数可以避免重复扫描相同记录或重复连接相同的表.
2.2.8 尽量多使用COMMIT
只要有可能,在程序中尽量多使用COMMIT, 这样程序的性能得到提高,需求也会因为COMMIT所释放的资源而减少:
COMMIT所释放的资源:
(1)回滚段上用于恢复数据的信息.
(2)被程序语句获得的锁
(3)redo log buffer 中的空间
(4)ORACLE为管理上述3种资源中的内部花费
2.2.9 用Where子句替换HAVING子句
避免使用HAVING子句, HAVING 只会在检索出所有记录之后才对结果集进行过滤. 这个处理需要排序,总计等操作. 如果能通过WHERE子句限制记录的数目,那就能减少这方面的开销.
2.2.10减少对表的查询
在含有子查询的SQL语句中,要特别注意减少对表的查询.例子:
SELECT TAB_NAME FROM TABLES WHERE (TAB_NAME,DB_VER) = ( SELECT TAB_NAME,DB_VER FROM TAB_COLUMNS WHERE VERSION = 604)
2.2.11通过内部函数提高SQL效率
复杂的SQL往往牺牲了执行效率. 能够掌握上面的运用函数解决问题的方法在实际工作中是非常有意义的。
2.2.12 使用表的别名(Alias)
当在SQL语句中连接多个表时, 请使用表的别名并把别名前缀于每个Column上.这样一来,就可以减少解析的时间并减少那些由Column歧义引起的语法错误.
2.2.13 用EXISTS替代IN、用NOT EXISTS替代NOT IN
在许多基于基础表的查询中,为了满足一个条件,往往需要对另一个表进行联接.在这种情况下, 使用EXISTS(或NOT EXISTS)通常将提高查询的效率. 在子查询中,NOT IN子句将执行一个内部的排序和合并. 无论在哪种情况下,NOT IN都是最低效的 (因为它对子查询中的表执行了一个全表遍历). 为了避免使用NOT IN ,我们可以把它改写成外连接(Outer Joins)或NOT EXISTS.
例子:
(高效)SELECT * FROM EMP (基础表) WHERE EMPNO > 0 AND EXISTS (SELECT ‘X' FROM DEPT WHERE DEPT.DEPTNO = EMP.DEPTNO AND LOC = ‘MELB')
(低效)SELECT * FROM EMP (基础表) WHERE EMPNO > 0 AND DEPTNO IN(SELECT DEPTNO FROM DEPT WHERE LOC = ‘MELB')
2.2.14用>=替代>
高效:
SELECT * FROM EMP WHERE DEPTNO >=4
低效:
SELECT * FROM EMP WHERE DEPTNO >3
两者的区别在于, 前者DBMS将直接跳到第一个DEPT等于4的记录而后者将首先定位到DEPTNO=3的记录并且向前扫描到第一个DEPT大于3的记录.
2.2.15总是使用索引的第一个列
如果索引是建立在多个列上, 只有在它的第一个列(leading column)被where子句引用时,优化器才会选择使用该索引. 这也是一条简单而重要的规则,当仅引用索引的第二个列时,优化器使用了全表扫描而忽略了索引。
2.2.16尽可能的用UNION-ALL 替换UNION
当SQL 语句需要UNION两个查询结果集合时,这两个结果集合会以UNION-ALL的方式被合并, 然后在输出最终结果前进行排序. 如果用UNION ALL替代UNION, 这样排序就不是必要了. 效率就会因此得到提高. 需要注意的是,UNION ALL 将重复输出两个结果集合中相同记录. 因此各位还是要从业务需求分析使用UNION ALL的可行性. UNION 将对结果集合排序,这个操作会使用到SORT_AREA_SIZE这块内存. 对于这块内存的优化也是相当重要的.
2.2.17 避免使用耗费资源的操作
带有DISTINCT,UNION,MINUS,INTERSECT,ORDER BY的SQL语句会启动SQL引擎执行耗费资源的排序(SORT)功能. DISTINCT需要一次排序操作, 而其他的至少需要执行两次排序. 通常, 带有UNION, MINUS , INTERSECT的SQL语句都可以用其他方式重写. 如果你的数据库的SORT_AREA_SIZE调配得好, 使用UNION , MINUS, INTERSECT也是可以考虑的, 毕竟它们的可读性很强
2.2.18 优化GROUP BY
提高GROUP BY 语句的效率, 可以通过将不需要的记录在GROUP BY 之前过滤掉.下面两个查询返回相同结果但第二个明显就快了许多.
低效:
SELECT JOB , AVG(SAL) FROM EMP GROUP by JOB HAVING JOB = ‘PRESIDENT' OR JOB = ‘MANAGER'
高效:
SELECT JOB , AVG(SAL) FROM EMP WHERE JOB = ‘PRESIDENT' OR JOB = MANAGER'
GROUP by JOB
三. 生成存储过程注释文档的Package
3.1 包的创建语句
/* Formatted on 2010/12/16 23:14:11 (QP5 v5.115.810.9015) */
CREATE OR REPLACE PACKAGE tools
AS
TYPE rctype IS REF CURSOR;
TYPE array_type
IS
TABLE OF VARCHAR2 (500)
INDEX BY BINARY_INTEGER;
FUNCTION iifn2 (bool IN BOOLEAN,
true_number IN VARCHAR2,
false_number IN VARCHAR2)
RETURN VARCHAR2;
PROCEDURE split (v_str1 IN VARCHAR2,
v_str2 IN VARCHAR2,
v_array OUT array_type,
v_count OUT NUMBER);
PROCEDURE getdoc (proc_name IN VARCHAR2, proc_num IN NUMBER);
PROCEDURE getdocs (v_type VARCHAR2);
PROCEDURE getsource (v_name VARCHAR2);
PROCEDURE update_moudle_sql (v_moudle NUMBER, v_text VARCHAR2);
PROCEDURE get_moudle_sql (v_moudle NUMBER);
END tools;
/
CREATE OR REPLACE PACKAGE BODY tools
AS
FUNCTION iifn2 (bool IN BOOLEAN,
true_number IN VARCHAR2,
false_number IN VARCHAR2)
RETURN VARCHAR2
IS
BEGIN
IF bool
THEN
RETURN true_number;
ELSIF NOT bool
THEN
RETURN false_number;
ELSE
RETURN NULL;
END IF;
END;
PROCEDURE split (v_str1 IN VARCHAR2,
v_str2 IN VARCHAR2,
v_array OUT array_type,
v_count OUT NUMBER)
IS
v_procName VARCHAR2 (50) := 'tools.split';
v_procPos VARCHAR2 (50) := 'start';
v_para VARCHAR2 (500);
v_error VARCHAR2 (500);
ch VARCHAR2 (10);
tmpstr VARCHAR (500);
str1 VARCHAR2 (4000);
j INT := 1;
BEGIN
--str1:=replace(trim(v_str1),chr(10));
str1 := TRIM (v_str1);
FOR i IN 1 .. LENGTH (str1)
LOOP
ch := SUBSTR (str1, i, 1);
IF ch <> v_str2
THEN
tmpstr := tmpstr || ch;
ELSE
IF TRIM (tmpstr) IS NOT NULL
THEN
v_array (j) := tmpstr;
j := j + 1;
tmpstr := '';
END IF;
END IF;
END LOOP;
IF TRIM (tmpstr) IS NOT NULL
THEN
v_array (j) := tmpstr;
END IF;
v_count := j;
EXCEPTION
WHEN OTHERS
THEN
ROLLBACK;
v_error := '未知异常';
runlog.errorlog (v_procname,
v_procpos,
v_para,
SQLCODE,
SQLERRM,
v_error);
COMMIT;
END split;
PROCEDURE getdoc (proc_name IN VARCHAR2, proc_num IN NUMBER)
IS
v_text VARCHAR2 (1000);
v_array tools.array_type; --split返回的数据
v_flag NUMBER; --代码位置的标志位
v_set_flag NUMBER; --是否设置标志位
v_count NUMBER; --split返回的数组的长度
v_modify_count NUMBER := 0;
v_tmp_num VARCHAR2 (50);
CURSOR proc_code
IS
SELECT line, text
FROM user_source
WHERE name = UPPER (proc_name)
ORDER BY line ASC;
BEGIN
--设置过程顺序号
IF proc_num IS NULL
THEN
v_tmp_num := '**';
ELSE
v_tmp_num := proc_num || '.';
END IF;
FOR pc IN proc_code
LOOP
v_text := TRIM (REPLACE (pc.text, CHR (10)));
IF v_text IS NOT NULL
THEN
tools.split (v_text,
' ',
v_array,
v_count);
--置标志位。
IF v_count >= 1
THEN
CASE LOWER (v_array (1))
WHEN 'procedure'
THEN
v_flag := 1;
v_set_flag := 1;
WHEN 'as'
THEN
v_flag := 2;
v_set_flag := 1;
WHEN 'is'
THEN
v_flag := 2;
v_set_flag := 1;
WHEN 'begin'
THEN
v_flag := 3;
v_set_flag := 1;
WHEN '/**'
THEN
v_flag := 4;
v_set_flag := 1;
WHEN '**/'
THEN
v_flag := 5;
v_set_flag := 1;
WHEN '/*/'
THEN
v_modify_count := v_modify_count + 1;
IF v_modify_count = 1
THEN
v_flag := 6;
v_set_flag := 1;
ELSE
v_flag := 7;
v_set_flag := 1;
END IF;
ELSE
v_set_flag := 0;
END CASE;
--格式化
CASE v_flag
WHEN 1
THEN
IF v_set_flag = 1
THEN
DBMS_OUTPUT.put_line('************************************************************');
DBMS_OUTPUT.put_line(v_tmp_num
|| REPLACE (
REPLACE (LOWER (v_text),
'procedure',
'存储过程名称:'),
'('
));
DBMS_OUTPUT.put_line('************************************************************');
ELSE
IF SUBSTR (v_text, 1, 2) = '--'
THEN
DBMS_OUTPUT.put_line (' 过程说明:');
DBMS_OUTPUT.put_line (
' ' || TRIM (SUBSTR (v_text, 5))
);
DBMS_OUTPUT.put_line (' 参数说明:');
ELSE
IF v_count >= 4
THEN
DBMS_OUTPUT.put_line(' '
|| RPAD (v_array (1), 20)
|| iifn2 (
v_array (2) = 'out',
'输出',
'输入'
)
|| ' '
|| RPAD (
REPLACE (
REPLACE (
v_array (3),
','
),
')'
),
12
)
|| SUBSTR (
TRIM (v_array (4)),
3
));
END IF;
END IF;
END IF;
WHEN 2
THEN
v_flag := 2;
WHEN 3
THEN
v_flag := 3;
WHEN 4
THEN
IF v_set_flag = 1
THEN
DBMS_OUTPUT.put_line (' 返回值说明:');
ELSE
DBMS_OUTPUT.put_line (' ' || v_text);
END IF;
WHEN 5
THEN
v_flag := 5;
WHEN 6
THEN
IF v_set_flag = 1
THEN
DBMS_OUTPUT.put_line (' 修改记录:');
ELSE
DBMS_OUTPUT.put_line (' ' || v_text);
END IF;
WHEN 7
THEN
EXIT;
ELSE
v_flag := v_flag;
END CASE;
END IF;
END IF;
END LOOP;
END;
PROCEDURE getdocs (v_type VARCHAR2)
AS
v_procName VARCHAR2 (50) := 'proc_getdocs';
v_procPos VARCHAR2 (50) := 'start';
v_para VARCHAR2 (500);
v_error VARCHAR2 (500);
proc_num NUMBER := 0;
v_tmp_type VARCHAR2 (50);
CURSOR proc_cursor
IS
SELECT DISTINCT name
FROM user_source
WHERE text LIKE v_tmp_type AND name LIKE 'PROC%'
ORDER BY name ASC;
BEGIN
v_tmp_type := '--' || v_type || '%';
DBMS_OUTPUT.put_line('auto generate by tools.getdocs '
|| TO_CHAR (SYSDATE, 'yyyy-mm-dd hh24:mi:ss'));
FOR pc IN proc_cursor
LOOP
proc_num := proc_num + 1;
tools.getdoc (pc.name, proc_num);
END LOOP;
EXCEPTION
WHEN OTHERS
THEN
ROLLBACK;
v_error := '未知异常';
runlog.errorlog (v_procname,
v_procpos,
v_para,
SQLCODE,
SQLERRM,
v_error);
COMMIT;
END;
PROCEDURE update_moudle_sql (v_moudle NUMBER, v_text VARCHAR2)
AS
v_array tools.array_type;
v_count NUMBER;
v_oldcount NUMBER;
BEGIN
tools.split (v_text,
CHR (10),
v_array,
v_count);
IF v_count <= 0
THEN
RETURN;
END IF;
DELETE sys_moudle_sql
WHERE moudle_id = v_moudle;
v_oldcount := sql%ROWCOUNT;
FOR i IN 1 .. v_count
LOOP
DBMS_OUTPUT.put_line (i || ' ' || v_array (i));
INSERT INTO sys_moudle_sql (moudle_id,
line,
text,
time_insert)
VALUES (v_moudle,
i,
v_array (i),
SYSDATE);
END LOOP;
DBMS_OUTPUT.put_line (
'删除' || v_oldcount || '行,增加' || v_count || '行'
);
COMMIT;
END;
PROCEDURE get_moudle_sql (v_moudle NUMBER)
AS
CURSOR cur_sql
IS
SELECT text
FROM sys_moudle_sql
WHERE moudle_id = v_moudle
ORDER BY line ASC;
BEGIN
FOR ms IN cur_sql
LOOP
DBMS_OUTPUT.put_line (ms.text);
END LOOP;
EXCEPTION
WHEN OTHERS
THEN
DBMS_OUTPUT.put_line ('error!!');
END;
PROCEDURE getsource (v_name VARCHAR2)
AS
CURSOR cur_sql
IS
SELECT text
FROM user_source
WHERE name = UPPER (v_name)
ORDER BY line ASC;
BEGIN
FOR ms IN cur_sql
LOOP
DBMS_OUTPUT.put_line (ms.text);
END LOOP;
EXCEPTION
WHEN OTHERS
THEN
DBMS_OUTPUT.put_line ('error!!');
END;
END tools;
/
脚本主要调用了USER_SOURCE来查看相关代码的SQL.
DBA_SOURCE describes the text source of all stored objects in the database.
USER_SOURCE describes the text source of the stored objects owned by the current user. This view does not display the OWNER column.
Column | Datatype | NULL | Description |
OWNER | VARCHAR2(30) | NOT NULL | Owner of the object |
NAME | VARCHAR2(30) | NOT NULL | Name of the object |
TYPE | VARCHAR2(12) |
| Type of object: FUNCTION, JAVA SOURCE, PACKAGE, PACKAGE BODY, PROCEDURE, TRIGGER, TYPE, TYPE BODY |
LINE | NUMBER | NOT NULL | Line number of this line of source |
TEXT | VARCHAR2(4000) |
| Text source of the stored object |
3.2 使用该包的注意事项
(1)存储过程SQL
CREATE OR REPLACE procedure proc_cust_buy_limit(
--客户的购买权限
v_custid in number, --客户id
v_wareid in number, --商品id
v_platid in number, --平台id
v_count in number, --购买数量
o_result out number, --返回值
o_detail out varchar2 --详细描述
)
as
v_procName varchar2(50):='proc_cust_buy_limit';
v_procPos varchar2(50):='start';
v_para varchar2(500);
v_error varchar2(500);
v_tmp_count number;
begin
/**
o_result
1验证成功
0 验证失败
-1 异常
**/
/*/
2010-8-19 建立过程
/*/
--存储过程SQL
end;
/
(2) 调用Pacakge
call TOOLS.GETDOC('proc_cust_buy_limit',10);
(3)输出结果
************************************************************
10.存储过程名称: proc_cust_buy_limit -- 这里的10与调用时的参数对应
************************************************************
过程说明:
客户的购买权限
参数说明:
v_custid 输入 number 客户id
v_wareid 输入 number 商品id
v_platid 输入 number 平台id
v_count 输入 number 购买数量
o_result 输出 number 返回值
o_detail 输出 varchar2 详细描述
返回值说明:
o_result
1验证成功
0 验证失败
-1 异常
修改记录:
2010-8-19 建立过程
小结:
无规矩不成方圆,每个公司都有自己的一套规范。
------------------------------------------------------------------------------
Blog: http://blog.csdn.net/tianlesoftware
网上资源: http://tianlesoftware.download.csdn.net
相关视频:http://blog.csdn.net/tianlesoftware/archive/2009/11/27/4886500.aspx
DBA1 群:62697716(满); DBA2 群:62697977(满)
DBA3 群:62697850 DBA 超级群:63306533;
聊天 群:40132017
--加群需要在备注说明Oracle表空间和数据文件的关系,否则拒绝申请