gyn

Win32下的Perl,无用的select,停滞的Tk,结束吧....

采编系统客户端网络的改造

     摘要: 采编系统客户端网络的改造   关键词: postgresql 数据库, vlan , acl ,三层交换,路由 ...  阅读全文

posted @ 2006-06-02 16:23 gyn_tadao 阅读(369) | 评论 (0)编辑 收藏

局域网电脑管理系统之二:华为s3236e交换机的配置

原先已经有了一台华为s3526e的三层交换机。考虑到兼容的因素,这次还是选用了相同的型号。

令人感到兴奋的是,新的s3526e在功能上有了不小的改进:
首先,增加了dhcp server的功能,就是说可以直接在交换机上做dhcp服务器,以前的及只能做relay,为此还不得不做一台dhcp服务器,麻烦程度可想而知。
第二,增加了am user-bind功能,方便ip地址的绑定。如果用acl的话需要很多步骤,我会在后面讲的。

从aux口接入配置线,另一头接电脑的com口。开启电脑的超级终端,设置为直接连接com口,中断位无,效验位无。这时,交换机可以通电了,超级终端立刻会有反映。

完全开启前可能会需要等待1、2分钟的时间,之后按enter键开始配置过程。

1:
super
sys
super password simple wahaha
sysname gyn_001
user-interf vty 0 4
authentication-mode passw
set authentication passw wahaha
quit
以上步骤为交换机取了个gyn_001的名字,同时设置高级模式3的密码为wahaha,设置telnet接入密码为wahaha

2:
vlan 100
quit
interf   v 100
ip addr 192.168.100.65 255.255.255.0
quit
这样就建立了一个三层地址为192.168.100.65的vlan 100

3:
vlan 100
port e0/2
quit
interf   e0/2
flow-control
quit
为vlan 77建立access口用来接入电脑,同时启动流控

4:
acl name net-forb-e2 link
rule 0 deny ingress interf e0/2 egress any
quit
packet-filter link-group net-forb-e2
封锁e0/2口,不允许接入电脑

5:
acl name net-mgr-e2 link
rule 0 permit ingress 0011-5b99-ed36 0-0-0 egress any
rule 1 permit ingress 000d-4c4c-5b19 0-0-0 egress any
quit
packet-filter link-group net-mgr-e2
开启mac地址为0011-5b99-ed36和000d-4c4c-5b19的两台电脑上网

以上两个步骤的顺序不可意对调,否则将无法达到控制外来电脑接入的功能。

6:
gvrp
vlan 500
quit
interf v 500
ip addr 192.168.65.21 255.255.255.240
quit
interf e0/1
port link-type trunk
port trunk permit vlan all
gvrp
quit
建立了一个与旧的三层交换机相对应的一个vlan,用来建立路由。这时可以用一根网线将两台交换机连起来了。

7:
ip route-static 192.168.6.0 255.255.255.0 192.168.65.25
ip route-static 192.168.0.200 255.255.255.255 192.168.65.25
建立到旧三层交换机的静态路由。当然最简单的办法就是建立一个缺省路由
ip route-static 0.0.0.0 0.0.0.0 192.168.65.25
只是出于安全的原因,我不希望让该网段的电脑能随便访问别的网段。

8:
在旧交换机上建立到新机器的静态路由
ip route-static 192.168.100.0 255.255.255.0 192.168.65.21

现在大功基本告成了。新交换机所连接的两台电脑只要手动配置ip地址,就可以访问服务器区的电脑并且可以上网了。为了方便其间最好用dhcp来分配并管理ip地址的使用。

9:
dhcp ena
interf v 100
dhcp select interf
这样就在vlan 100中启动了dhcp服务器

为了管理方便,将绑定一些经常搞破坏的电脑的ip地址

10:
acl绑定法:
acl number 1
rule 0 permit source 192.168.100.2 0
quit
acl number 200
rule 0 deny ingress 0011-5b99-ed36 0-0-0 egress any
rule 1 permit ingress 0011-5b99-ed36 0-0-0 egress any
quit
packet-filter link-group 200 rule 0
packet-filter ip-group 0 rule 0 link-group 200 rule 1

am绑定法:
am ena
am user-bind ip_addr 192.168.100.2 mac_addr 0011-5b99-ed36

相比之下am绑定法显然简单不少,但据说很消耗资源,并且可绑定的上限就100多台,所以还是用了acl绑定法。

11:
quit
save
quit
最后,保存并退出。

到这里为止,全部搞定。

posted @ 2006-05-29 21:27 gyn_tadao 阅读(677) | 评论 (0)编辑 收藏

tcl精鼎B5100上安装RH9的一些经验

之前是装过debian的,很方便的,但对中文的支持不好,所以就放弃了。
RH9已经很老了,所以一直担心对这台相对较新的电脑支持不好,事实上也验证了我的想法。
装完之后,显示器频率只能定在60Hz,相当闪烁。用redhat-config-xfreevid调了一下,不见效果。又在参数文件中锁定85Hz,重启还是没有用。到intel网站下载linux用显卡驱动,是tar.gz包,安装有点麻烦,但还算顺利,重启后依旧没用。最后想起在debian里时,好像是用的vesa驱动,立即试了一下,成功!
声卡无法检测,于是安装alsa万能驱动,重启后发现声卡,但检测发声不正常(放屁状),只有升级内核,这就麻烦了,日后再说。
再root中service postgresql start,解锁postgres用户,重设密码,su进入后,createuser个人用户,允许createdb,不允许createuser,su个人用户。现在可以使用数据库了。
基本上还算可以,就是数据库版本老了点,7.3.4的。在postgresql官方网站上没用找到8.1.3的RH9安装包,连8.0的也没有,估计已经停止支持了。
凑活用吧~~:->

posted @ 2006-05-22 21:57 gyn_tadao 阅读(776) | 评论 (3)编辑 收藏

用来建立“局”文中数据库的脚本

create table net_top(switch_pos int, floor int);
create table net_port(room int primary key, port1 int default 0, port2 int default 0);
create table net_mac_addr(room int references net_port(room),
mac_addr varchar(30) unique check (mac_addr ~ '^(00)[0-9A-F]{10}$'),
ip_addr varchar(30) check (ip_addr ~ '[0-9]{3}(\.[0-9]{1,3}){3}$'),
owner varchar(20)
);
create view net_room_view as
select * from net_top t left outer join net_port p
on (p.room/100=t.floor or p.room=t.floor);
create view net_owner_view as
select n.room, n.mac_addr, n.ip_addr, n.owner, p.port1, p.port2
from net_mac_addr n left outer join net_port p
on (n.room=p.room);

存在'E:\dbase_related\net_mgr.sql'中,然后在命令行中执行
psql -U postgres -f e:\dbase_related\net_mgr.sql
就行了。

posted @ 2006-05-15 21:25 gyn_tadao 阅读(213) | 评论 (0)编辑 收藏

局域网电脑管理系统之一:信息数据库的架构

局域网电脑管理系统之一

信息数据库的架构

 

使用 postgresql8.1 建立信息数据库。

 

建立三张表:

ü      交换机分布表: net_top

ü      办公室与井道端口对应表: net_port

ü      mac 地址表: net_mac_addr

o_dp.jpg

建立的程序如下:

       create table net_top(

              switch_pos integer,

              floor integer

       );

       create table net_port(

              room integer,

              port1 integer,

              port2 integer

       );

       create table net_mac_addr(

              room integer,

              mac_addr varchar(30),

              ip_addr varchar(30),

              owner varchar(20)

       );

 

建立视图 net_room_port ,将表 1 2 连接起来。

create view net_room_view as

  select * from net_top t left outer join net_port p

on (p,room/100=t.floor);


o_net_room_port.jpg

 

3 张表添加约束,使之能正确得存储。

       net_port 中,将 room 设为主键:

              alter table net_port add constraint room_prim primary key (room);

       net_mac_addr 中将 room 设为 net_port.room 的外键:

              alter table net_mac_addr

add foreign key (room) references net_port;

       net_mac_addr 中设置 mac_addr ip_addr 的检查:

              alter table net_mac_addr add constraint mac_check check

(mac_addr ~ ‘^(00) [0-9A-Z]{10 }$’);

              alter table net_mac_addr add constraint ip_check

                     check (ip_addr ~ ‘[0-9]{3}(\.[0-9]){1,3}$’);

 

表建立以后,就要进行数据输入。

 

1 :输入表 1 的数据:

       新建一个文本文键 e:\switch.txt ,在其中输入数据,如下:

2       1

2       2

2       3

6       4

6       5

6       6

8       7

8       8

8       9

8       10

12     11

12     12

12     13

12     14

12     15

保存后,将该文本内容拷贝至表 1 中。

copy net_top from ‘e:/switch.txt’;


o_net_top.jpg
 

2 :输入表 2 的内容

       新建一个文本文键 e:\room.txt ,编写一个脚本用来输入房间号:

      

open(FILE,'>e:/switch.txt');

 

for($init=1; $init<=15; $init++){

              for($temp=1; $temp<=15; $temp++){

                     $sum=$init*100+$temp;

                     print FILE "$sum"."\n";

              }

}

 

close FILE;

 

       然后根据大楼井道分布图所示,将端口填入,以下是其中的一部分:

       1011040

102   1160

103   1050

104   1030

105   1060

106   0     0

107   1070

108   0     0

109   1080

110   0     0

11     0     0

112   0     0

113   109110

114   0     0

115   0     0

201   2040

202   2010

总共 228 个数据。需要提醒的是,以上所有数据行中的数据都用制表符

分割。保存后,将该文本内容拷贝至表 1 中。

copy net_port from ‘e:/room.txt’;


o_net_port.jpg
 

3 :输入表 3 的内容

这是最艰巨的,需要一台电脑接着一台得打入 ipconfig –all ,然后在逐一输入。为了简化操作,写了一组采集程序。

服务器端的程序如下:

 

$in_buffer=undef;

$PF_INET=2;

$port=2345;

$local_addr=pack('SnC4x8',$PF_INET,$port,192,168,138,105);

$SOCK_DGRAM=2;

 

 

 

socket(UDP_SERVER,$PF_INET,$SOCK_DGRAM,getprotobyname('udp')) or die("$!");

bind(UDP_SERVER,$local_addr) or die("$!");

listen(UDP_SERVER,100);

 

print("waiting for connection...\n");

$count=0;

 

while(1){

  print $count." connection..\n";

  $count++;

  if(recv(UDP_SERVER,$in_buffer,100,0)){

         open(FILE,'>>e:/mac_addr.txt');

         chomp($in_buffer);

         print FILE $in_buffer."\n";

         close FILE;  

  }

  else{next;}

}

 

 

close(UDP_SERVER);


o_net_mgr_serv.jpg
 

 

客户端的程序如下:

@stack=();

$mac_addr=undef;

$ip_addr=undef;

 

print(' 请输入您的办公室门牌号码: ');

$room_num=<STDIN>;

chomp($room_num);

 

print(' 请输入您的姓名拼音: ');

$name=<STDIN>;

chomp($name);

 

open(FOO,'-|',"ipconfig -all");

 

while(<FOO>){

  chomp();

  if($_=~s/(.*)(00(\-[0-9A-Z]{2}){5})(.*)/$2/){

         $mac_addr=join('',split(/-/,$_));

  }

  if($_=~/IP Address/){

         $_=~s/(.*)([0-9]{3}(\.[0-9]{1,3}){3})(.*)/$2/;

         $ip_addr=$_;

  }

}

 

close FOO;

 

push(@stack, $room_num);

push(@stack, $mac_addr);

push(@stack, $ip_addr);

push(@stack, $name);

$out_buffer=join("\t",@stack);

print $out_buffer."\n";

 

$PF_INET=2;

$port=2345;

$remote_addr=pack('SnC4x8',$PF_INET,$port,192,168,138,105);

$SOCK_DGRAM=2;

socket(UDP_CLIENT,$PF_INET,$SOCK_DGRAM,getprotobyname('udp'));

send(UDP_CLIENT,$out_buffer,0,$remote_addr);

close(UDP_CLIENT);

 

exit;

   

 

o_net_mgr_cli.jpg
 

采集的数据被记录到服务器中:

o_mac_addr.jpg 

 

然后将数据导入数据库:

copy net_mac_addr from ‘e:/mac_addr.txt’;

 

o_net_mac_addr.jpg
 

posted @ 2006-05-11 21:37 gyn_tadao 阅读(399) | 评论 (0)编辑 收藏

perl编程:尼科彻斯定理

5月8日的电脑报上有一个小测试:
任何一个整数的立方都可以写成一串连续奇数的和。
想也没想,就写了:

use strict;

my $seed=<STDIN>;
$seed**=3;
my @stack=();
open(NKCS,'>c:/code/nkcs.txt');

for(my $init=1; $init<=$seed; $init+=2){
   my $sum=$init;
   my $temp=$init;
   while($sum<$seed){
      push(@stack,$temp);
      $temp+=2;
      $sum+=$temp;
   }
   if($sum==$seed){
      while(@stack){print NKCS shift(@stack)."\n" ;}
      close NKCS;
      exit;
   }
   undef @stack;
}

close NKCS;
die("nkcs failed");

posted @ 2006-05-08 14:01 gyn_tadao 阅读(249) | 评论 (0)编辑 收藏

perl编程:一个链表类

package data_string;

sub new{
 shift();
 my $val=undef;
 my $ref=undef;
 ($val,$ref)=@_;
 my $new_string={
  val => $val,
  ref => $ref
  };
 bless $new_string, data_string;
 return $new_string;
}

#return a reference to the hash holding two incoming parameters which are value of the node and a #reference to a next node

sub val{
 return shift()->{val};
}

#return the value of the node

sub ref{
 return shift()->{ref};
}

#return a reference to the following node

sub setval{
 my $tnode=shift();
 if(@_){
  my $tval=shift();
  $tnode->{val}=$tval;
  return 1;
 }
 return 0;
}

#set the node with a new value

sub setref{
 my $tnode=shift();
 my $tref=shift();
 if(CORE::ref($tnode)){
  $tnode->{ref}=$tref;
  return 1;
 }
 return 0;
}

#set the node with a new reference

sub setnull{
 undef %{shift()};
 return 1;
}

#undefine the node

sub length{
 my $count=0;
 my $head=shift();
 while( defined($head) ){ $count++; $head=$head->ref;}
 return $count;
}

#return the length of a list whose head is the current node

sub insert{
 my $head=shift();
 my $pos=undef;
 my $str=undef;
 if(@_==2){
  ($pos, $str)=@_;
  if($pos>=$head->length && $pos<0)
   {return 0;}
  else
   {
   my $pre=$head;
   my $cur=$pre->ref;
   my $index=0;
   while($index!=$pos && defined($cur)){
     $pre=$cur;
     $cur=$cur->ref;
     $index++;
   }#while
   $pre->setref(data_string->new($str, $cur)); 
   return 1;
   }#else
 }
 return 0;
}

#insert the current node leading list a new node taking the incoming parameter as the value

sub delete{
 if($_[1]==0){
  if($_[0]->length==1){shift()->setnull; return 1;}
  else{
   my $fir=shift;
   my $sec=$fir->ref;
   $fir->setval($sec->val);
   $fir->setref($sec->ref);
   $sec->setnull;
   return 1;
  }
 }
 my $head=shift();
 if(@_){
  my $pos=shift();
  if($pos>=$head->length && $pos<=0)
   {return 0;}#if
  else{
   my $pre=$head;
   my $cur=$pre->ref;
   my $index=1;
   while($index<$pos){
    $pre=$cur;
    if(defined($cur)){$cur=$cur->ref;}
    $index++; 
   }#while
   $pre->setref($cur->ref);
   $cur->setnull;
   return 1;
  }#else
 }#if
 return 0;
}

#delete the current node leading list a node whose position is related to the incoming parameter

1;


#写了个测试程序:

use data_string;

$temp=undef;
$node=data_string->new(1, $temp);

foreach (qw(2 3 4 5)){
 $ind=$_-2;
 if($ind<$node->length){
  $node->insert($ind, $_);
 }
}

$node->delete(3);

$temp=$node;

while(defined($temp)){
 print($temp->val."\n");
 $temp=$temp->ref;
}

r_data_string.jpg

posted @ 2006-04-29 19:21 gyn_tadao 阅读(972) | 评论 (0)编辑 收藏

perl编程:一个简单的链表

sub sinode{
 my %node=(val=>undef, ref=>undef);
 if(@_>1){
  $node{val}=shift();
  $node{ref}=shift();
  }
 else{
  if(@_=1){
   $node{val}=shift();
   }
  }
 return \%node;
}

$temp=undef;

foreach (qw(5 4 3 2 1)){
 $node=sinode($_, $temp);
 $temp=$node;
}

do{
 printf("$node->{val}\n");
 $node=$node->{ref};
}until($node eq undef)

r_simple_string.jpg
 

posted @ 2006-04-29 13:51 gyn_tadao 阅读(278) | 评论 (0)编辑 收藏

pl/sql异常处理(4)

oracle-plsql 异常处理( 4

异常处理

 

当异常生成之后,程序被中止,控制权交给异常处理模块,异常处理模块捕获当前异常句柄,并交由相应的程序处理;如果,异常促里模块没有捕捉到异常句柄,那么它将被传输到当前程序的外围。

 

除非由一些特殊的要求,一般情况下异常将再当前程序的异常处理模块中被处理。异常处理模块以 EXCEPTION 开始 END; 结尾。

       Declare

              /*…………*/

       begin

              /*…………*/

       exception

              when /* 异常名称 */

              then /* 异常处理 */

              when other

              then /* 异常处理 */

       end;

异常处理模块的语法基本上以 CASE 一致,凡是在 when 中有定义的异常都将被处理,而没有的则被传输。一个特殊的异常处理语句是 WHEN OTHERS 。就想在( 3 )中所说的,它会处理所有为被处理的异常,因此必须小心使用它,最好是在最外层的程序中。当然如果喜欢偷懒的,大可以在异常处理模块中只放一个 OTHERS 。注意,无论哪种情况, OTHERS 只能这只在异常处理的最后一位。

 

有趣的是,可以在一个 when 中处理多个异常句柄。

       Exception

              When no_data_found or invalid_employee_id or dbms_ldap.invalid session

              Then /*………..*/

       End;

       /

在这个例子里,有标准包的异常、自定义异常和非标准包中的异常。这些异常只能用 or 连接,不可以用 and ,因为只有一个异常能够生成。

 

raise_application_error 生成的异常,如果没有被处理而一直传递到系统环境中,那么环境将视情况作出相应的反映。在 sqlplus 中, oracle 将回滚所有 DML 对数据所做的修改。在 sqlplus 环境中,因为有自动回滚的存在,我们可以保留出现未被处理的异常的可能性;而在另外的一些环境中,则需要仔细设计最外层程序。

ü         捕捉任何有可能传出的异常。

ü         记录错误以便于分析。

ü         给外部环境一个信息,以便于其作出相应的处理。

 

对于自定义异常,因为 sqlcode 值永远是 1 ,所以当它被传出时,如果外围程序中没有定义相同名称的异常,我们将不知道是什么异常产生了。因此,不要将自定义异常传递出去。

 

在程序中处理几个互相独立的操作时,为了避免出现因为一个操作产生异常而使整个程序被中断的情况,有必要将这些独立的操作放在各自的虚拟块中。

       Procedure change_data is

       Begin

              Begin

                     Delete from employee where …..

              Exception

                     When others then null;

              End;

 

              Begin

                     Update company set …….

              Exception

When others then null;

              End;

 

              Begin

                     Insert into company_history select * from company where ….

              Exception

                     When others then null;

              End;

       End;

       /

 

 

Pl/sql 提供了一些内建的函数来帮助我们确定、分析异常。

 

SQLCODE

这个函数在前面有提到过,它是一个用于返回当前模块中最近一次异常值的函数,或者说是非入栈程序的异常值。打个比方:如果在当前程序的异常模块中调用了另一个程序, oracle 将当前程序及相应的环境变量(包括异常值)压入系统栈;在被调用程序中生成了一个值为 1 的异常,那么 sqlcode 将返回 1 ;之后刚才的程序出栈, sqlcode 返回当前异常值。需要注意的是,不要在异常模块之外使用它,这样不会有任何意义。当没有异常或在异常模块之外使用时, SQLCODE 返回 0 ;返回值 1 是指自定义异常。

 

SQLERRM

接收异常值,返回相应的长度不超过 512 字节的描述语。如果没有传入异常值,则返回当前异常描述。

       Begin

              Dbms_output.put_line( sqlerrm(-1403);

       End;

Sql>/

Ora-1403: no data found

在需要体构长度超过 512 字节的描述时, oracle 建议使用 dbms_utility.format_error_stack 。显然,用这个函数来判断一个异常是否为系统异常是很有用的,如果不是的话,将返回以下两种情况的一种。

如果是一个负数:

       ora-nnnnn: message not found,; product=rdbms; facility=ora

如果是一个正数:

       -nnnnn: non-oracle exception

 

DBMS_UTILITY.FORMAT_ERROR_STACK

返回当前异常相应的描述,没有字符长度限制。与 SQLCODE 相同的是,必须在异常处理模块中使用。虽然名称中有一个 stack 在,但通过它并不能知道异常的最初生成处,需要的话就必须使用 DBMS_UTILITY.FORMAT_ERROR_BACKTRACE

 

DBMS_UTILITY.FORMAT_ERROR_BACKTRACE

系统为最近一次生成的异常设置了一个栈,并跟踪它的传递过程,而这个函数使用这个栈,然后返回该异常的整个传递过程。这个函数对错误的定位和实施下一步处理起着至关重要的作用。

       Create or replace procedure procl is

       Begin

              Dbms_output.put_line(‘running proc1’);

              Raise no_data_found;

       End;

       /

       create or replace procedure proc2 is

       begin

              dbms_output.put_line(‘calling proc1’);

              proc1;

       end;

       /

       create or replace procedure proc3 is

       begin

              dbms_output.put_line(‘calling proc2’);

              proc2;

       exception

              when no_data_found

              then

                     dbms_output.put_line(‘error stack at top level’);

                     dbms_output.put_line(dbms_utility.format_error_backtrace);

       end;

       /

现在可以运行 proc3 来看看结果。

Sql>set serveroutput on;

Sql>begin

2                         dbms_output.put_line(‘proc3->proc2->proc1 backtrace’);

3                         proc3;

4     end;

5     /

    Proc3 -> Proc2 -> Proc1 backtrace

    calling proc2

    calling proc1

    running proc1

    Error stack at top level:

    ORA-06512: at "SCOTT.PROC1", line 4

    ORA-06512: at "SCOTT.PROC2", line 5

ORA-06512: at "SCOTT.PROC3", line 4

事实上,每次异常的产生都将重置这个异常栈,只是最后一次从系统栈出栈的是最外层的程序块,所以可以清楚地看到异常生成的整个过程。上面这个程序的执行过程是这样的:首先用 put_line 打印 Proc3 -> Proc2 -> Proc1 backtrace 调用 proc3 ,当前程序入栈 => 打印 calling proc2 ,调用 proc2 proc3 入栈 => 打印 calling proc1 ,调用 proc1 proc2 入栈 => 打印 running proc1 ,生成 no_data_found 异常,该异常被压入异常栈中 =>  proc2 出栈,并检测到来自第 5 行调用传递过来的异常,将它在此压入异常栈 => proc3 出栈,并检测到来自第 4 行调用传递过来的异常,将它在此压入异常栈, dbms_utility.format_error_backtrace 将异常栈中信息反相打印出来 =>  最外层程序出栈, end

以下是正确使用这个函数的一些注意事项:

ü         在当前程序的异常处理模块中调用这个函数。

ü         避免在中间程序中使用异常处理模块。

这样异常就能被正确地传输到最外层程序中,并打印出这个过程了。

 

 

posted @ 2006-04-28 14:58 gyn_tadao 阅读(914) | 评论 (0)编辑 收藏

pl/sql异常处理(3)

Oracle:pl/sql 异常处理3)

生成错误

 

处理 oracle 系统自动生成系统异常外,可以使用 raise 来手动生成错误。

l         Raise exception;

l         Raise package.exception;

l         Raise;

以上是 raise 的三种使用方法。第一种用于生成当前程序中定义的异常或在 standard 中的系统异常。

       Declare

              Invalid_id exception;

              Id_values varchar(2);

       Begin

              Id_value:=id_for(‘smith’);

              If substr(id_value,1,1)!=’x’

              Then

                     Raise invalid_id;

              End if;

       Exception

              When invalid_id

              Then

                     Dbms_output.put_line(‘this is an invalid id!’);

       End;

这是一个生成自定义异常的例子,当然也可以生成系统异常:

       declare

              employee_id_in number;

       Begin

Select employee_id into employee_id_in from employ_list where employee_name=&n;

If employee_id_in=0

Then

       Raise zero_devided;

End if;

       Exception

              When zero_devided

              Then

                     Dbms_output.put_line(‘wrong!’);

       End;

有一些异常是定义在非标准包中的,如 UTL_FILE DBMS_SQL 以及程序员创建的包中异常。可以使用 raise 的第二种用法来生成异常。

       If day_overdue(isbn_in, browser_in) > 365

       Then

              Raise overdue_pkg.book_is_lost

       End if;

在最后一种 raise 的形式中,不带任何参数。这种情况只出现在希望将当前的异常传到外部程序时。

       Exception

              When no_data_found

              Then

                     Raise;

       End;

 

Pl.sql 使用 raise_application_error 过程来生成一个有具体描述的异常。当使用这个过程时,当前程序被中止,输入输出参数被置为原先的值,但任何 DML 对数据库所做的改动将被保留,可以在之后用 rollback 命令回滚。下面是该过程的原型:

       Procedure raise_application_error(

       Num binary_integer;

       Msg varchar2;

       Keeperrorstack Boolean default false

)

其中 num 是在 -20999 -20000 之间的任何数字(但事实上, DBMS_OUPUT DBMS_DESCRIBLE 包使用了 -20005 -20000 的数字); msg 是小于 2K 个字符的描述语,任何大于 2K 的字符都将被自动丢弃; keeperrorstack 默认为 false ,是指清空异常栈,再将当前异常入栈,如果指定 true 的话就直接将当前异常压入栈中。

    CREATE OR REPLACE PROCEDURE raise_by_language (code_in IN PLS_INTEGER)

    IS

       l_message error_table.error_string%TYPE;

    BEGIN

       SELECT error_string

         INTO l_message

         FROM error_table, v$nls_parameters v

        WHERE error_number = code_in

          AND string_language  = v.VALUE

          AND v.parameter = 'NLS_LANGUAGE';

 

       RAISE_APPLICATION_ERROR (code_in, l_message);

    END;

posted @ 2006-04-26 09:59 gyn_tadao 阅读(356) | 评论 (0)编辑 收藏

仅列出标题
共11页: First 3 4 5 6 7 8 9 10 11 
<2008年9月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

导航

统计

常用链接

留言簿(15)

随笔分类(126)

随笔档案(108)

相册

搜索

最新评论

阅读排行榜

评论排行榜