pragma 用法简介

原创 2013年12月01日 22:50:15

Pragma在PL/SQL编程过程中属于预定义命令,预定义的内容包含以下四点

exception_init绑定错误号

serially_reusable继续可重用包

restrict_references定义函数纯度

autonomous_transaction定义程序块为独立事务


1.exception_init

用于在pl/sql程序块中绑定错误号,就是给错误号取个别名

declare
    exce exception;
    pragma exception_init(exce,-20001);
 begin
    raise_application_error(-20001,'错误信息');  
 exception
    when exce then 
        dbms_output.put_line(sqlerrm);
 end;
执行结果:

ORA-20001: 错误信息
同时我们也可以看看不使用exception_init时如何来捕获异常的

declare
    --exce exception;
    --pragma exception_init(exce,-20001);
 begin
    raise_application_error(-20001,'错误信息');  
 exception
    when others then 
        if sqlcode=-20001 then
            dbms_output.put_line(sqlerrm);
        end if;
 end;
注:sqlcode返回错误号,如-20001,-123等等

sqlerrm返回详细错误信息,如ORA-20001: 错误信息

2.serially_reusable

将此pl/sql程序包定义为可重用包。
若未定义serially_reusable时,程序包变量在同一个会话调用时,上一次对变量值的修改将影响到接下来的使用;若加上定义之后,在下个程序块使用包时将重新初始化这个包状态。
还是弄个简单的东东看下效果
先看看没有加serially_reusable时定义
create or replace package test
is
    n number:=1;
    --pragma serially_reusable;
end test;

create or replace package body test
is
  --pragma serially_reusable;  
       
end test;

下面是调用部分
begin
dbms_output.put_line(test.n);
test.n:=10;
dbms_output.put_line(test.n);
end;

begin
dbms_output.put_line(test.n);
end;

输出结果如下
1
10
10
结果很明显,在同一个会话中调用时,包变量的值在下一个程序块中也是10

然后我们看看加上serially_reusable会怎么样。
create or replace package test
is
    n number:=1;
    pragma serially_reusable;
end test;

create or replace package body test
is
  pragma serially_reusable;  
       
end test;
执行调用代码后结果如下
1
10
1

注:调用都要在同一个会话中,否则加不加都不会影响到下次的调用。
加了pragma serially_reusable;之后包内的程序块就不能再修改包变量了?这个还不是非常确定
从原理上讲,若没有加时,第一次调用一个包时会在uga(会话专用内存块?)中存在一个包使用缓存保存下包的相应信息;否则就不会将包在块调用之后就即时清除掉包调用信息。

3.autonomous_transaction

将所在子程序块标注为独立事务块,即在此块中执行的事务命令不影响亦不受外部调用块的事务命令影响。
示例代码
create table temp
        (des varchar2(100));--创建表
create or replace procedure temp_proc(val varchar2)
is
    pragma autonomous_transaction;
begin 
    insert into temp values(val);
    --update temp set des=val;
    commit;
    --rollback;
end;
begin
    insert into temp values('first');
    temp_proc('second');
    commit;
end;
select * from temp;
drop table temp;
drop procedure temp_proc;
查询结果为
first
second
我们再看另一段代码
create table temp
        (des varchar2(100));--创建表
create or replace procedure temp_proc(val varchar2)
is
    --pragma autonomous_transaction;
begin 
    insert into temp values(val);
    --update temp set des=val;
    commit;
    --rollback;
end;
begin
    insert into temp values('first');
    temp_proc('second');
    rollback;
end;
select * from temp;
drop table temp;
drop procedure temp_proc;

结果依然是
first
second
虽然在调用块中使用了rollback命令,但是"first"依然被插入进去了,因为存储过程里的commit语句影响了事务的提交。
注:1.加上pragma autonomous_transaction标识后,本块在begin...end部分要明确使用commit/rollback命令对本块事务进行处理。
2.在代码块中像下面这样调用会报错,求个解决方法。
begin

    declare
        pragma autonomous_transaction;
    begin
        --代码
        null;
    end;
        --代码
    null;
end;

4.restrict_references

定义函数纯度,因函数的调用位置可能对函数有一定的影响,用于对相应程序块中的PL/SQL语句进行限制。总共分为四个级别
wnds(Writes no database state):函数不修改数据库
rnds (reads no database state)函数不查询数据库表
wnps(writes no package state)函数不改变包变量的值
rnps(reads no package state)函数不引用包变量的值
...
具体的可以参看oracle 9i pl/sql开发人员指南5.4.2。
若有不对的地方,请指正




oracle中关键字pragma解释

PRAGMA是一个编译指示(或命令)。 ====== 编译指示在编译时被处理,它们不在运行时执行 ===== 编译指示是对编译程序发出的特殊指令。 ===== 它也称为伪指令(pseudo...
  • cuiyan1982
  • cuiyan1982
  • 2015年05月28日 15:30
  • 770

Oracle PRAGMA RESTRICT_REFERENCES 理解

一 介绍:在Oracle application developer's guide --fundmental中9-60(oracle9i)有介绍,copy一点给你先看看。Using Pragma R...
  • wangshengfeng1986211
  • wangshengfeng1986211
  • 2010年10月29日 17:15
  • 3453

#pragma 预处理指令详解

#pragma  预处理指令详解              在所有的预处理指令中,#pragma 指令可能是最复杂的了,它的作用是设定编译器的状态或者是指示编译器完成一些特定的动作。#pragma指令...
  • jx_kingwei
  • jx_kingwei
  • 2005年04月28日 22:35
  • 34098

#pragma与_Pragma

  C90为预处理指令家族带来一位新成员:#pragma。一般情况下,大家很少见到它。       #pragma的作用是为特定的编译器提供特定的编译指示,这些指示是具体针对某一种(或某一些)编译器的...
  • yy_msdn
  • yy_msdn
  • 2008年04月04日 15:52
  • 2155

#pragma 的几种用法

预编译指令#pragma有很多种用法,我敢保证很多程序员即使是一辈子也不会碰到其中的有些用法,是的,他们的确很偏僻,我们也没有用他们的需求。所以,本文不会面面俱到,只是把几种常用的几种汇总了一下。1....
  • hziee_
  • hziee_
  • 2007年09月15日 17:47
  • 3372

c++中#pragma的用法

c++中#pragma的用法 在所有的预处理指令中,#Pragma 指令可能是最复杂的了,它的作用是设定编译器的状态或者是指示编译器完成一些特定的动作。#pragma指令对每个编译器给出了一个方...
  • zaishaoyi
  • zaishaoyi
  • 2015年06月16日 13:41
  • 3749

重要的#pragma声明

最近在做CCP标定的底层的相关工作,涉及到对多组变量指定内存区块的应用。转载了这篇文章来学习#pragma的使用。   原文出处:龙丘推荐必读基础知识: 重要的#pragma声明 http://www...
  • wzj983
  • wzj983
  • 2017年04月29日 17:11
  • 607

#pragma comment 的使用方法

#pragma comment ( lib,"wpcap.lib" ) 表示链接wpcap.lib这个库。和在工程设置里写上链入wpcap.lib的效果一样,不过这种方法写的 程序别人在使用你的代码的...
  • liruda
  • liruda
  • 2008年03月30日 14:48
  • 50427

C语言#pragma预处理

在所有的预处理指令中,#pragma 指令可能是最复杂的了,它的作用是设定编译器的状态或者是指示编译器完成一些特定的动作。#pragma 指令对每个编译器给出了一个方法,在保持与C 和C ++语言完全...
  • phenixyf
  • phenixyf
  • 2016年11月01日 10:15
  • 573

#pragma的用法

本附录介绍了 C++ 编译器 pragma。pragma 是一个编译器指令,使用它可以向编译器提供其他信息。该信息可以更改您所控制的编译详细信息。例如,pack pragma 会影响结构内的数据布局。...
  • lowfly_xy
  • lowfly_xy
  • 2010年03月24日 23:57
  • 2092
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:pragma 用法简介
举报原因:
原因补充:

(最多只允许输入30个字)