ORACLE数据库开发经验总结

来源:互联网 发布:虚拟仿真实验室软件 编辑:程序博客网 时间:2024/04/28 14:20
 

  ORACLE数据库作为大型数据库管理系统,近年来一直占有世界上高端数据库的最大份额,其强大而完善的数据库管理功能,以及ORACLE公司推陈出新的不断努力,一直成为IT业界瞩目的焦点。岭澳核电站的数据库平台采用了ORACLE7.3作为后端平台,前端选择了ORACLE公司的DEVELOPER 2000 及DESIGNER2000作为开发工具,采用了目前流行的CLIENT/SERVER模式。本人在ORACLE系统的开发中,就ORACLE的整套开发工具提出一些自己的体会,供同行参考。

  一. ORACLE SQL PLUS 使用技巧:

  ----①查找重复记录:

  SELECT DRAWING,DSNO FROM EM5_PIPE_PREFAB

  WHERE ROWID!=(SELECT MAX(ROWID) FROM EM5

  _PIPE_PREFAB D

  WHERE EM5_PIPE_PREFAB.DRAWING=D.DRAWING AND

  EM5_PIPE_PREFAB.DSNO=D.DSNO);

  ----执行上述SQL语句后就可以显示所有DRAWING和DSNO相同且重复的记录。

  ----删除重复记录:

  DELETE FROM EM5_PIPE_PREFAB

  WHERE ROWID!=(SELECT MAX(ROWID) FROM EM5

  _PIPE_PREFAB D

  WHERE EM5_PIPE_PREFAB.DRAWING=D.DRAWING AND

  EM5_PIPE_PREFAB.DSNO=D.DSNO);

  ----执行上述SQL语句后就可以刪除所有DRAWING和DSNO相同且重复的记录。

  ----② 快速编译所有视图

  ----当在把数据库倒入到新的服务器上后(数据库重建),需要将视图重新编译一遍,因为该表空间视图到其它表空间的表的连接会出现问题,可以利用PL/SQL的语言特性,快速编译。

  SQL >SPOOL ON.SQL

  SQL >SELECT ‘ALTER VIEW ‘||TNAME||’

  COMPILE;’ FROM TAB;

  SQL >SPOOL OFF

  然后执行ON.SQL即可。

 SQL >@ON.SQL

  当然,授权和创建同义词也可以快速进行,如:

  SQL >SELECT ‘GRANT SELECT ON ’

  ||TNAME||’ TO USERNAME;’ FROM TAB;

  SQL >SELECT ‘CREATE SYNONYM

  ‘||TNAME||’ FOR USERNAME.’||TNAME||’;’ FROM TAB;

  ③ 用外联接提高表连接的查询速度

  在作表连接(常用于视图)时,常使用以下方法来查询数据:

  SELECT PAY_NO, PROJECT_NAME

  FROM A

  WHERE A.PAY_NO NOT IN (SELECT PAY_

  NO FROM B WHERE VALUE >=120000);

  ----但是若表A有10000条记录,表B有10000条记录,则要用掉30分钟才能查完,主要因为NOT IN要进行一条一条的比较,共需要10000*10000次比较后,才能得到结果。该用外联接后,可以缩短到1分左右的时间:

  SELECT PAY_NO,PROJECT_NAME

  FROM A,B

  WHERE A.PAY_NO=B.PAY_NO(+)

  AND B.PAY_NO IS NULL

  AND B.VALUE >=12000;

  ----④ 怎样读写文本型操作系统文件

  ----在PL/SQL 3.3以上的版本中,UTL_FILE包允许用户通过PL/SQL读写操作系统文件。如下:

  DECALRE
  FILE_HANDLE UTL_FILE.FILE_TYPE;
  BEGIN
  FILE_HANDLE:=UTL_FILE.FOPEN(
  ‘C:/’,’TEST.TXT’,’A’);
  UTL_FILE.PUT_LINE(FILE_HANDLE,’
  HELLO,IT’S A TEST TXT FILE’);
  UTL_FILE.FCLOSE(FILE_HANDLE);
  END;

  ----相关UTL_FILE数据库包详细信息可以参见相关资料。

  ----⑤ 怎样在数据库触发器中使用列的新值与旧值

  ----在数据库触发器中几乎总是要使用触发器基表的列值,如果某条语句需要某列修改前的值,使用:OLD就可以了,使用某列修改后的新值,用:NEW就可以了。如:OLD.DEPT_NO,:NEW.DEPT_NO。

  二.ORACLE DEVELOPER 2000使用技巧:

  ----① 改变FORM(FMX模块)运行时的Runform4.5的题头:

  ----DEVELOPER2000中FMX默认题头为:Developer/2000 Forms Runtime for Windows 95 / NT 你可以改为自己定义的标题,

  ----1. 在Form级触发器中添加触发WHEN-NEW-FORM-INSTANCE

  ----2. 在此触发器中写如下代码:

  set_window_property(FORMS_MDI_WINDOW,TITLE,'POINT

  SYSTEM 欢迎使用');

  ----② 如何隐藏菜单中的window选项:

  ----在创建自己的菜单时,最后选项总有window项,下面介绍如何去掉它,

  ----1. 创建一个Menu

  ----2. 在Menu中建立一个Item,命名为WINDOW。

  ----3. 设置该Item属性如下:

  ----Menu Item Type:Magic

  Command Type:Null

  Magic Item:Window

  Lable:为空

 ----③ 怎样创建动态下拉列表List

  ----Developer 2000 中的列表是通过设置相关属性而完成数据项的列表设置的,但那只是静态的,有时你想让某项成为动态的列表,随输入数据的改变而改变,就需要动手去编个小程序。下面详细介绍怎样去做:

  ----有块EBOP_CABLE_ACCOUNT,下有SPECIFICATION数据项,当一进入该模块时,就将SPECIFICATION项在数据库中存储的值动态显示出来,先在Form4.5中建立一个PRCEDURE,命名为DYN_LIST:

  PROCEDURE DYN_LIST IS
  CURSOR C1 IS
  SELECT DISTINCT(SPECIFICATION)
  FROM EBOP_CABLE_ACCOUNT;
  CNT NUMBER;
  i NUMBER;
  TNAME EBOP_CABLE_
  ACCOUNT.SPECIFICATION%TYPE;
  BEGIN
  CLEAR_LIST('EBOP_CABLE_
  ACCOUNT.SPECIFICATION');
  SELECT COUNT(DISTINCT
  (SPECIFICATION)) INTO CNT FROM EBOP
  _CABLE_ACCOUNT;
  open C1;
  FOR i IN 1..CNT LOOP
  FETCH C1 INTO TNAME;
  EXIT WHEN C1%NOTFOUND
  OR C1%NOTFOUND IS NULL;
  ADD_LIST_ELEMENT
  ('EBOP_CABLE_ACCOUNT
  .SPECIFICATION',i,TNAME,TNAME);
  END LOOP;
  DELETE_LIST_ELEMENT
  ('EBOP_CABLE_ACCOUNT.SPECIFICATION',CNT+1);
  CLOSE C1;
  END;

  然后在FORM的WHEN-NEW

  -FORM-INSTANCE触发子中加入一行:

  DYN_LIST;

  ----这样一进入该FMX,就会动态刷新该列表。除此之外,SPECIFICATION数据项改为列表项。

  ----④ 当显示多条记录且数据项特别多时,如何组织录入及显示界面:

 ----如上图所示,PRN代码及设备代码在画布1(CONTENT型)上,其它数据项在画布2(STACK型)上,所有数据项为一个表的列或一个块的数据项。在拉动水平滚动条时或用TAB或敲回车键时,将看到全部数据项。这种排布方法适用于数据项特别多又想显示多条记录时用。主要制作顺序为:先建立两个画布,画布1(CONTENT型),画布2(STACK型),然后建立块,选画布时用画布1,这样所有项都显示在画布1上,然后选中除PRN代码及设备代码之外的所有数据项,选TOOLS菜单下的PROPERTIES选项,将这些数据项的CANVAS属性选为画布2(STACK型),然后调整整体位置就可以了。

  ----⑤ 如何在FORM的受限触发子中提交保存数据

  ----在FORM中很多触发子是不能用COMMITWORK语句的,当你在该触发子中使用了UPDATE,DELETE等操作并想立即存盘时,就需要COMMITWORK语句了。首先在服务器端建立DB_SQL_COMMIT这个过程(采用ORACLE7.3数据库),

  PROCEDURE DB_SQL_COMMIT IS
  source_cursor integer;
  ignore integer;
  V7 NUMBER :=2;
  BEGIN
  source_cursor:=dbms_sql.open_cursor;
  dbms_sql.parse(source_cursor,'COMMIT WORK',V7);
  ignore:=dbms_sql.execute(source_cursor);
  DBMS_SQL.CLOSE_CURSOR(source_cursor);
  END;

  ----然后在FORM中该触发子中调用过程DB_SQL_COMMIT;就可以了,当然你可以根据自己需要将该过程加入参数,这样通过参数可以得到执行DML语句的权限。

  ----⑥ 如何在FORM中实现某数据项自动按记录序号加一操作

  ----设块名为VO,要操作的数据项为VO_ID,在该块中建立块级触发子WHEN-CREATE- RECORD,加入如下代码:

  :VO_ID:=:System.Trigger_Record;

  ----这样每当生成新记录时VO_ID就会自动加一了。

  ----⑦ 如何在一个FORM中调用另一个FORM,或在一个块中调用另一个块时显示特定的记录有时用户会要求在调用另一个FORM时,只显示相关的记录,举例如下,在一个FORM的块中有一个按钮,在按钮触发子中加入如下代码:

  DECLARE
  PM
  PARAMLIST;
  BEGIN
  PM:=GET_PARAMETER_LIST('PM');
  IF NOT ID_NULL(PM) THEN
  DESTROY_PARAMETER_LIST('PM');
  END IF;
  PM:=CREATE_PARAMETER_LIST('PM');
  ......................
  ADD_PARAMETER(PM,'THE_WHERE',
  TEXT_PARAMETER,'EM_NAME=''EM4''
  AND EM_PROJECT_NAME=''支架预制''');
  OPEN_FORM('PAYMENT',ACTIVATE,SESSION,PM);
  END;
----其中EM_NAME,EM_PROJECT_NAME为本FORM某块的数据项,PAYMENT为要调用的FORM模块。这样通过传递参数列表就可以得到想要的结果。在FORM.PAYMENT.FMB中,建立一参数THE_WHERE,CHAR型,长1000,然后在PAYMENT.FMB中建立FORM级触发子WHEN-NEW-FORM-INSTANCE,在该触发子中加入以下语句:

  IF :PARAMETER.THE_WHERE IS NOT NULL THEN

  SET_BLOCK_PROPERTY('PAYMENT',

  DEFAULT_WHERE,:PARAMETER.THE_WHERE);

  END IF;

  ----其中PAYMENT为要显示的块,这样通过参数传递就得到想要的某些特定条件的数据了。

  ----⑧ 在FORM中当有主从块时,连续输入记录如何避免被不断的提示保存:

  ----每输入一条主记录和若干条该主记录的从记录后,此时再导航到主块输下一条记录,FORM就会提示你是否要保存记录,而你并不希望FORM提示,让它自动保存,此时你可以到Program Units中找到过程PROCEDUREClear_All_Master_Details,然后在这个过程中找到语句

  Clear_Block(ASK_COMMIT);

  ----将其改为Clear_Block(DO_COMMIT);就可以了。

  ----⑨ 在Report开始时选择排序项:

  ----在报表开始的Parameter Form中选择报表按哪个数据项排序,

  ----1. 先在USER PARAMETER 中创建SORT参数,为字符型,长20。

  ----2. 初始值选’责任方’,然后将这四个值输入到DATA SELECTION中,形成列表。

  ----3. 然后处理QUERY中的SQL语句:

  select CHARGER,FCO_NO,EM_NAME,FCO

  _NO,DESCRIPTION, FCR_POINT

  from FCR_MAIN

  ORDER BY DECODE(:SORT,'责任方',CHARGER,'FCO号',

  FCO_NO,'FCR号',FCR_NO,'FCR号',EM_NAME)

  ----⑩ 在Developer 2000中如何读写操作系统文件

  ----在用Developer 2000的开发工具开发应用程序时,经常碰到需要读写外部文件的问题,可以用ORACLE 带的包TEXT_IO来完成这项需求。例如:

DECLARE
  IN_FILE TEXT_IO.FILE_TYPE;
  OUT_FILE TEXT_IO.FILE_TYPE;
  LINE_BUFER VARCHAR2(80);
  /*若不用IN_FILE,可以将各字段联接在一起赋值给此变量*/
  BEGIN
  IN_FILE:=TEXT_IO.FOPEN
  (‘C:/TEMP/TEST1.TXT’,’r’);
  OUT_FILE:=TEXT_IO.FOPEN
  (‘C:/TEMP/TEST2.TXT’,’w+’);
  LOOP
  TEXT_IO.GET_LINE(IN_FILE,LINE_BUFER);
  TEXT_IO.PUT(LINE_BUFER);
  TEXT_IO.NEW_LINE;
  TEXT_IO.PUT_LINE(OUT_FILE,LINE_BUFER);
  END LOOP;
  EXCEPTION
  WHEN no_data_found THEN
  TEXT_IO.PUT_LINE(‘CLOSING THE FILE ,PLEASE WAITING....’);
  TEXT_IO.FCLOSE(IN_FILE);
  TEXT_IO.FCLOSE(OUT_FILE);
  END;

  三.数据库管理

  ----① 在删除一个表中的全部数据时,须使用TRUNCATE TABLE 表名;因为用DROP TABLE,DELETE *FROM表名时,TABLESPACE表空间该表的占用空间并未释放,反复几次DROP,DELETE操作后,该TABLESPACE上百兆的空间就被耗光了。

  ----② 数据库文件的移动方法

  ----当想将数据库文件移动到另外一个目录下时,可以用ALTER DATABASE命令来移动(比ALTER TABLESPACE适用性强):

  ----1. 使用SERVER MANAGER关闭实例.

  SVRMGR > connect internal;

  SVRMGR > shutdown;

  SVRMGR >exit;

  ----2. 使用操作系统命令来移动数据库文件位置(假设这里操作系统为SOLARIS 2.6). 在UNIX中用 mv命令可以把文件移动到新的位置,

  #mv /ora13/orarun/document.dbf /ora12/orarun

----3. 装载数据库并用alter database命令来改变数据库中的文件名.

  SVRMGR > connect internal;

  SVRMGR > startup mount RUN73;

  SVRMGR > alter database rename file

  > ‘/ ora13/orarun/document.dbf’

  > ‘/ ora12/orarun/document.dbf’;

  ----4. 启动实例.

  SVRMGR > alter database open;

  ----(huangfutong@china.com)

  ----ORACLE数据库开发经验总结


原创粉丝点击