因为所有的操作最终都作用在基表上,因此基表名和列名的变化会对这些语句产生影响,此时必须修改所有的语句,这样不但麻烦,有时甚至会发生错误。另外,有的甚至表名和列名复杂而晦涩,用起来极不方便。怎样才能解决这个问题呢?避免直接依赖于基表的问题,方法有:
●使用视图为表名和列名起别名,在应用过程中可以借助视图中的名字来代替基表名和列名,当表名和列名改变时,只需改变相应视图的定义即可。
●类似于视图定义,只不过提供了一种更直接更广泛的方法来为各种对象定义别名,其中也包括视图对象。
●在程序中用定义光标的方法防止直接依赖于表。当表名改变时,只需改变光标定义即可。
一、使用视图(略)
二、使用同义名
1、简介
和使用视图来实现操作不直接依赖于基表一样,同义名也能实现这一目的。与视图不同的是同义名不但可以应用在表的命名中,同样也可以应用在视图、序列、存储过程和函数以及包中,因此它的应用范围更广泛。用同义名的不便之处是它不能对列起别名,这一点不如视图。
创建同义名的语法如下所示:
create [public]synonym 同义名 for 对象;
其中:
●public:公共同义名,所有用户都可以引用,若省略此关键字不写,则默认是private同义名,即私有同义名,它只能为某一用户使用。
●同义名:为对象起的别名,在以后使用对象时可以用此名来代替原对象名。
●对象:某一特定对象名,它可以是基表、视图、序列、过程、存储函数、存储包和其它同义名,指定对象时可以指定所属用户,中间用“.”分开。
2、具体操作
●创建私有同义名
【例】为persons表起同义名为person。
sql>create synonym person for persons;
此外用的是默认private同义名,只能为当前用户使用。若要指定其为另一用户使用,比如用户jxl,则可用以下语句创建。
sql>create synonym person fro jxl.persons;
●创建公共同义名
也可以创建公共同义名给所有用户使用
【例】
sql>create public synonym person fro persons;
●使用同义名
创建了同义名之后,就可以在其他地方引用它,以此来代替基表的引用。如下所示:
sql>insert into person values(98036,'Skert','W',to_date('25-OCT-71'));
在以后使用过程中,若基表的名字变了,只需修改同义名的定义即可。但同义名创建不支持replace命令,因此必须将其删除再重新创建。删除命令如下:
sql>drop synonym person;
若persons表更名为persons_information,则重新定义同义名如下:
sql>create synonym person for persons_information;
这样和使用视图一样,所有引用同义名的地方不必做任何改动。
●删除同义名
若一个对象(如表)被删除了,则同时也要将相应的同义名删除,因为此时再引用同义名将产生错误,另外也为了清理数据字典。删除同义名语法如下:
drop [public] synonym;
其中的public在删除公共同义名的情况下使用,若删除某一个用户的同义名,则必须加上用户名。前面定义的3种同义名分别删除如下:
sql>drop synonym person;
sql>drop synonym jxl.person;
sql>drop public synonym person;
在分布式数据库系统中,同义名意义更大。因为在分布式环境中,既可以使用本地的数据库对象,也可以引用其它地方的数据库对象,而且不同地方的对象可能同名。这样在引用对象时,必须指明所在的位置。但若引用了同义名,则可以将位置隐藏起来,使所有对象透明使用,这样便可以适应各种变化而简化应用。
三、使用光标
1、简介
在存储过程和函数中可以使用显式光标,光标相当于定义了一个查询,在以后应用中可能用这个光标的查询结果。
当表名改变时,在存储过程和函数中只需改变定义在这个表上的光标即可,后面对光标的引用不用变,从而避免了直接依赖于表的操作。
2、具体操作
●在程序中使用光标
【例】
declare
person_no number(5);
person_name char(10);
person_sex char(1);
cursor person is select no,name,sex from persons where no<98050;
begin
open person;
fetch person into person_no,person_name,person_sex;
loop
exit when person%NOTFOUND;
if person_sex='M' then
insert into MAN values(person_no,person_name);
else
insert into WOMAN values(person_no,person_name);
end if;
fetch person into person_no,person_name,person_sex;
end loop;
close person;
end;
这段PL/SQL程序实现将男女员工分别登记在MAN、WOMAN表中的功能,它用到了一个光标person。可以看到,在程序体中,虽然引用了表persons的内容,但却没有引用persons表名,而只是在光标定义时引用了一次。
●修改光标定义以适应变化
当将persons表名改为persons_information时,只需将光标定义处的表名修改一下即可,而程序将完成相同的功能。
【例】光标定义如下所示:
cursor person is
select no,name,sex
from persons_information
where no<98050;
这个程序比较短,即使不用光标也没多大关系。当应用程序很大时,就有必要考虑光标的使用,并且最好将所有存储过程和函数放到一个包中。这样,只需对光标定义一次,便可以在所有过程和函数中使用。
当然,使用光标也有自己的缺点,它并不能直观地解决直接信赖于表的问题,光标在网络数据库中对减少网络传输量的用途更大一些。
(摘自Oracle 9i简明教程 清华大学出版社)