PLSQL部分(引david博客)
◆结果集缓存(Result Set Caching)
这一特性能大大提高很多程序的性能。在一些MIS系统或者OLAP系统中,需要使用到很多"select count(*)"这样的查询。在之前,我们如果要提高这样的查询的性能,可能需要使用物化视图或者查询重写的技术。在11g,我们就只需要加一个/*+result_cache*/的提示就可以将结果集缓存住,这样就能大大提高查询性能。当然,在这种情况下,我们可能还要关心另外一个问题:完整性。因为在oracle中是通过一致性读来保证数据的完整性的。而显然,在这种新特性下,为提高性能,是从缓存中的结果集中读取数据,而不会从回滚段中读取数据的。关于这个问题,答案是完全能保证完整性。因为结果集是被独立缓存的,在查询期间,任何其他DML语句都不会影响结果集中的内容,因而可以保证数据的完整性。
◆对象依赖性改进
在11g之前,如果有函数或者视图依赖于某张表,一旦这张表发生结构变化,无论是否涉及到函数或视图所依赖的属性,都会使函数或视图变为invalid。在11g中,对这种情况进行了调整:如果表改变的属性与相关的函数或视图无关,则相关对象状态不会发生变化。
◆正则表达式的改进
在10g中,引入了正则表达式。这一特性大大方便了开发人员。11g,oracle再次对这一特性进行了改进。其中,增加了一个名为regexp_count的函数。另外,其他的正则表达式函数也得到了改进。
◆新SQL语法 =>
我们在调用某一函数时,可以通过=>来为特定的函数参数指定数据。而在11g中,这一语法也同样可以出现在sql语句中了。例如,你可以写这样的语句:
select f(x=>6) from dual; |
◆对TCP包(utl_tcp、utl_smtp…)支持FGAC(Fine Grained Access Control)安全控制
◆增加了只读表(read-only table)
在以前,我们是通过触发器或者约束来实现对表的只读控制。11g中不需要这么麻烦了,可以直接指定表为只读表。
◆触发器执行效率提高了
内部单元内联(Intra-Unit inlining)
在C语言中,你可以通过内联函数(inline)或者宏实现使某些小的、被频繁调用的函数内联,编译后,调用内联函数的部分会编译成内联函数的函数体,因而提高函数效率。在11g的plsql中,也同样可以实现这样的内联函数了。
◆设置触发器顺序
可能在一张表上存在多个触发器。在11g中,你可以指定它们的触发顺序,而不必担心顺序混乱导致数据混乱。
◆混合触发器(compound trigger)
这是11g中新出现的一种触发器。她可以让你在同一触发器中同时具有申明部分、before过程部分、after each row过程部分和after过程部分。
◆创建无效触发器(Disabled Trigger)
11g中,开发人员可以可以闲创建一个invalid触发器,需要时再编译她。
◆在非DML语句中使用序列(sequence)
在之前版本,如果要将sequence的值赋给变量,需要通过类似以下语句实现:
select seq_x.next_val into v_x from dual; |
在11g中,不需要这么麻烦了,下面语句就可以实现:
v_x := seq_x.next_val; |
◆PLSQL_Warning
11g中,可以通过设置PLSQL_Warning=enable all,如果在"when others"没有错误爆出就发警告信息。
◆PLSQL的可继承性
可以在oracle对象类型中通过super(和java中类似)关键字来实现继承性。
◆编译速度提高
因为不在使用外部C编译器了,因此编译速度提高了。
◆改进了DBMS_SQL包
其中的改进之一就是DBMS_SQL可以接收大于32k的CLOB了。另外还能支持用户自定义类型和bulk操作。
◆增加了continue关键字
在PLSQL的循环语句中可以使用continue关键字了(功能和其他高级语言中的continue关键字相同)。
◆新的PLSQL数据类型——simple_integer
这是一个比pls_integer效率更高的整数数据类型。
对上面的自己写个package,涵盖下新特性,但未涉及触发器
CREATE OR REPLACE PACKAGE func_test_11g IS
PROCEDURE p_show_last_n(n INTEGER);
FUNCTION fun_plus_one(i PLS_INTEGER) RETURN PLS_INTEGER RESULT_CACHE;
END func_test_11g;
CREATE OR REPLACE PACKAGE BODY func_test_11g IS
--RESULT_CACHE CACHE 函数
FUNCTION fun_plus_one(i pls_integer) RETURN PLS_INTEGER RESULT_CACHE IS BEGIN RETURN i+1; END;
PROCEDURE p_show_last_n(n INTEGER) IS
v_f PLS_INTEGER := 0;
--新增数据类型 simple_integer 是pls_integer的子集
v_f3 simple_integer := -1;
v_f2 simple_integer :=0;
v_text varchar2(70):='AAbbbAAb3477AA77777@345AA6fh\ AA';
BEGIN
dbms_output.put_line( v_text );
--新的函数调用方式,用来赋值
SELECT fun_plus_one(i=>v_f) INTO v_f3 FROM dual;
FOR i IN 1 .. 100
LOOP
v_f3 := 1 + i;
IF (v_f3 < n)
THEN
--continue子句
continue;
ELSE
--正则表达式 新增REGEXP_COUNT
dbms_output.put_line(v_f3||' '||REGEXP_COUNT(v_text, 'AA', 1, 'i')||' AA');
END IF;
END LOOP;
EXCEPTION
WHEN OTHERS THEN
NULL;
END p_show_last_n;
END func_test_11g;
Warning部分
SQL> exec DBMS_WARNING.set_warning_setting_string ('ENABLE:ALL', 'SESSION');
SQL> begin
2 -- Call the procedure
3 func_test_11g.p_show_last_n(n =>'99');
4 end;
5 /
AAbbbAAb3477AA77777@345AA6fh\ AA
99 5 AA
100 5 AA
101 5 AA
PL/SQL procedure successfully completed
SQL> show errors;
No errors
SQL> CREATE FUNCTION f1(i pls_integer) RETURN PLS_INTEGER RESULT_CACHE IS BEGIN RETURN i+'1'; END;
2 /
Function created
SQL> show errors;
Errors for FUNCTION HUA.F1:
LINE/COL ERROR
-------- -----------------------------------------------------------------------------
1/1 PLW-05018: unit F1 omitted optional AUTHID clause; default value DEFINER used
trigger的触发顺序
If two or more triggers with different timing points are defined for the same statement on the same table, then they fire in this order:
-
All
BEFORE
STATEMENT
triggers -
All
BEFORE
EACH
ROW
triggers -
All
AFTER
EACH
ROW
triggers -
All
AFTER
STATEMENT
triggers
同一张表上with the same timing point的,可以指定FOLLOWS
andPRECEDE
语句来决定触发顺序。
SQL> CREATE OR REPLACE TRIGGER trg_11g_1
2 BEFORE INSERT OR UPDATE OR DELETE ON TEST_11g
3 FOR EACH ROW
4 BEGIN
5 DBMS_OUTPUT.PUT_LINE('trigger trg_11g_1 is fired ');
6 END;
7 /
Trigger created
SQL> CREATE OR REPLACE TRIGGER trg_11g_2
2 BEFORE INSERT OR UPDATE OR DELETE ON TEST_11g
3 FOR EACH ROW
4 FOLLOWS trg_11g_1
5 BEGIN
6 DBMS_OUTPUT.PUT_LINE('trigger trg_11g_2 is fired ');
7 END;
8 /
Trigger created
SQL> CREATE OR REPLACE TRIGGER print_test_11g
2 FOR INSERT OR UPDATE OR DELETE ON TEST_11g
3 FOLLOWS trg_11g_2
4 COMPOUND TRIGGER
5 BEFORE STATEMENT IS
6 BEGIN
7 DBMS_OUTPUT.PUT_LINE('trigger print_test_11g Before statement section is fired ');
8 END BEFORE STATEMENT;
9 BEFORE EACH ROW IS
10 BEGIN
11 DBMS_OUTPUT.PUT_LINE('trigger print_test_11g Before trigger section is fired ');
12 DBMS_OUTPUT.PUT('Old object_id = ' || :OLD.object_id || ', ');
13 DBMS_OUTPUT.PUT_LINE('New object_id = ' || :NEW.object_id || ', ');
14 DBMS_OUTPUT.PUT('Old object_name = ' || :OLD.object_name || ', ');
15 DBMS_OUTPUT.PUT_LINE('New object_name= ' || :NEW.object_name || ', ');
16 END
17 BEFORE EACH ROW;
18 AFTER EACH ROW IS
19 BEGIN
20 DBMS_OUTPUT.PUT_LINE('trigger print_test_11g After trigger section is fired ');
21 DBMS_OUTPUT.PUT('Old object_id = ' || :OLD.object_id || ', ');
22 DBMS_OUTPUT.PUT_LINE('New object_id = ' || :NEW.object_id || ', ');
23 DBMS_OUTPUT.PUT('Old object_name = ' || :OLD.object_name || ', ');
24 DBMS_OUTPUT.PUT_LINE('New object_name= ' || :NEW.object_name || ', ');
25 END
26 AFTER EACH ROW;
27 AFTER STATEMENT IS
28 BEGIN
29 DBMS_OUTPUT.PUT_LINE('trigger print_test_11g after statement');
30 END
31 AFTER STATEMENT;
32 END;
33 /
Trigger created
插入一条数据,查看触发顺序
SQL> insert into test_11g values(3,'c',sysdate);
trigger print_test_11g Before statement section is fired
trigger trg_11g_1 is fired
trigger trg_11g_2 is fired
trigger print_test_11g Before trigger section is fired
Old object_id = , New object_id = 3,
Old object_name = , New object_name= c,
trigger print_test_11g After trigger section is fired
Old object_id = , New object_id = 3,
Old object_name = , New object_name= c,
trigger print_test_11g after statement
1 row inserted
改变触发顺序后
trigger print_test_11g Before statement section is fired
trigger trg_11g_2 is fired
trigger print_test_11g Before trigger section is fired
Old object_id = , New object_id = 3,
Old object_name = , New object_name= c,
trigger trg_11g_1 is fired
trigger print_test_11g After trigger section is fired
Old object_id = , New object_id = 3,
Old object_name = , New object_name= c,
trigger print_test_11g after statement
1 row inserted
一点要讲的是 这样的话,如果触发器我触发你,你触发我,会报 ORA-25023: Cyclic trigger dependency is not allowed
可以通过先drop掉原先的触发器重建
注意的是 You can specify PRECEDES only for a reverse crossedition trigger.