ITPub博客

首页 > 数据库 > Oracle > Oracle 11g笔记

Oracle 11g笔记

原创 Oracle 作者:imlihj2007 时间:2009-04-17 07:29:32 0 删除 编辑

Oracle 11g笔记

*开头的是我们可以考虑用到的,#是

没有用到新功能,没有符号是我暂时

不明白部分----------------------

2009-3-11 ***

*分区

间隔分区:

特点:自动添加分区(自动分区删除暂时没有做出来)

create table sales6

(

sales_id number,

sales_dt date

)

partition by range (sales_dt)

interval (numtoyminterval(1,'MONTH'))

(

partition p0701 values less than (to_date('2009-02-01','yyyy-mm-dd'))

);

--插入数据

insert into sales6 values (1,to_date('2009-04-01','yyyy-mm-dd'));

insert into sales6 values (1,to_date('2009-05-01','yyyy-mm-dd'));

insert into sales6 values (1,to_date('2009-01-07','yyyy-mm-dd'));

insert into sales6 values (2,to_date('2009-09-07','yyyy-mm-dd'));

--查询数据

select * from sales6 partition for (to_date('2009-04-05','yyyy-mm-dd'));

select * from sales6 partition for (to_date('2009-05-07','yyyy-mm-dd'));

select * from sales6 partition for (to_date('2009-01-07','yyyy-mm-dd'));

--自动添加可以

select *

from user_tab_partitions

where table_name = 'SALES6';

虚拟分区:

特点:使用不存在的列进行分区

create table sales5

(

sales_id number,

sales_dt varchar2(14),

sales_dt1 date

generated always as

(

to_date(sales_dt,'yyyymmddhh24miss')

) virtual

)

partition by range (sales_dt1)

interval (numtoyminterval(1,'MONTH'))

(

partition p0701 values less than (to_date('2007-02-01','yyyy-mm-dd'))

);

insert into sales5(sales_id,sales_dt) values (1,'20090401000000');

insert into sales5(sales_id,sales_dt) values (1,'20090501000000');

insert into sales5(sales_id,sales_dt) values (1,'20090701000000');

引用分区:

特点:使用外健分区

create table customers

(

cust_id number primary key,

cust_name varchar2(200),

rating varchar2(1) not null

)

partition by list (rating)

(

partition pA values ('A'),

partition pB values ('B')

);

/*create table sales

(

sales_id number primary key,

cust_id number not null,

sales_amt number,

constraint fk_sales_01

foreign key (cust_id)

references customers

);*/

create table sales

(

sales_id number primary key,

cust_id number not null,

sales_amt number,

constraint fk_sales_01

foreign key (cust_id)

references customers

)

partition by reference (fk_sales_01);

系统分区:

特点:自动分区,但是没有发现其优点

create table sales3

(

sales_id number,

product_code number,

state_code number

)

partition by system

(

partition p1 tablespace users,

partition p2 tablespace users

);

select partition_name from user_segments where segment_name = 'SALES3';

insert into sales3 partition (p1) values (1,101,1);

insert into sales3 values (1,101,1);--会有问题的!

总结:

间隔分区和虚拟分区联合使用可以满足个别要求!

*不可见的索引

特点:相当于特殊索引,避免执行计划的影响

create table sales ( sales_id number, cust_id number, sales_amt number, sale_category varchar2(6) generated always as ( case when sales_amt <= 10000 then 'LOW' when sales_amt > 10000 and sales_amt <= 100000 then 'MEDIUM' when sales_amt > 100000 and sales_amt <= 1000000 then 'HIGH' else 'ULTRA' end ) virtual );

insert into sales (sales_id, cust_id, sales_amt) values (1,1,100);insert into sales (sales_id, cust_id, sales_amt) values (2,102,1500);insert into sales (sales_id, cust_id, sales_amt) values (3,102,100000);select * from sales; create index in_sales_cat on sales (sale_category);

alter index in_sales_cat invisible;

总结:

这个功能在以后可能会很有用的!!!!!!!!!!!!!!!!!!!

*只读表

特点:可以固定一个特定的表

alter table sales read only;

delete sales

alter table sales read write;

select read_only from user_tables where table_name = 'SALES';

可以用来测试环境!·N

*井井有条的序列

特点:序列的使用将会变的更加简单

以前,如果您需要在 PL/SQL 程序中使用序列,则在该版本推出之前,您需要使用 SELECT .NEXTVAL INTO FROM DUAL 之类的结构。

declare

trans_id number(10);

begin

select myseq.nextval

into trans_id

from dual;

end;

现在不再需要这样了。您可以将序列的下一个值直接赋值给一个变量:

declare

trans_id number(10);

begin

trans_id := myseq.nextval;

end;

/

总结:

可以更加简化代码的开发!

*添加具有默认值的列

特点:Oracle 将从数据字典获取默认值并将其返回给用户尽管对该特性感到满意,Jill 还在考虑与第一个问题相关的另一个问题。她希望添加 TAX_CODE 列,但该列不能为空。显然,当她向非空表添加非空列时,还必须指定默认值“XX”。因此,她编写了以下 SQL:

alter table sales add tax_code varchar2(20) default 'XX' not null;

但她在这里停下了。SALES 表十分巨大,大约有 4 亿行。她知道,在执行该语句时,Oracle 会立即添加该列,但在将控制权返回给她之前将更新所有行中的值“XX”。更新 4 亿行不仅要花费很长时间,还要填充还原段、生成大量重做任务并产生极大的性能开销。因此,Jill 必须在“安静时段”(即,停机期间)才能进行此更改。

Oracle 数据库 11g 中有更好的方法吗?

当然有。上述语句将不会对表中的所有记录执行更新。尽管对于列值将自动设为“XX”的新记录来说,这不是问题,但当用户选择现有记录的该列时,这将返回 NULL,是吗?

实际上并非如此。当用户选择现有记录的列时,Oracle 将从数据字典获取默认值并将其返回给用户。这样,您就实现了一箭双雕:可以将一个新列定义为非空并具有默认值,同时不会导致任何重做和还原开销。真棒!

很不错的选择!!!!!!

总结:

没有测试!

*嵌套表的新功能

这个没有做测试,可以直接对嵌套表进行比较处理!

*透明数据加密

特点:可以透明个别数据

11G测试没有通过

万能密钥存储在数据库外一个称为“钱夹”的地方 — 默认位置在 $ORACLE_BASE/admin/$ORACLE_SID/wallet。在概念上,它类似于下图。

在配置 TDE 之后 — 或者更明确地说是配置了钱夹和万能密钥之后 — 您可以使用它来保护数据值。要为表的一列加密,需要使用以下 SQL

alter system set encryption key authenticated BY "topSecret"; 运行老是出问题! create table accounts

(

acc_no number not null,

first_name varchar2(30) not null,

last_name varchar2(30) not null,

SSN varchar2(9) ENCRYPT USING 'AES128',

acc_type varchar2(1) not null,

folio_id number ENCRYPT USING 'AES128',

sub_acc_type varchar2(30),

acc_open_dt date not null,

acc_mod_dt date,

acc_mgr_id number

)

在这里,您在列 SSN 和 FOLIO_ID 上使用了 TDE,它们现在以加密方式存储在表本身。但是,当用户从表中选择时,她看到以明文表示的数据,因为在检索过程中已经完成了解密。如果磁盘被盗,则包含在表段中的信息仍然保持加密状态。盗窃者需要表密钥才能看到加密的值,但是要获得表密钥,他需要万能密钥,而万能密钥存储在外部,因此无法获得。

注意列 SSN 和 FOLIO_ID 后面的子句,这些子句指定 ENCRYPT 使用 128 位高级加密标准。

这个功能可能会用到!

总结:

这个功能没有做出来!

#PL/SQL 中的条件编译:一次编写,多次执行

特点:???

这个我们暂时用不到!!

你们中很多人曾经使用过 C 语言,它支持编译器指令的概念。在 C 程序中,根据相关编译器的版本,特定变量的值有可能不同。

在 Oracle 数据库 10g 第 2 版中,PL/SQL 有一个类似的特性:现在可以提供预处理器指令,它们在编译期间而不是在运行时进行求值。例如,让我们创建一个非常简单的返回字符串的函数。

create or replace function myfunc

return varchar2

as

begin

$if $$ppval $then

return 'PPVAL was TRUE';

$else

return 'PPVAL was FALSE';

$end

end;

注意第 5 行,您已经使用预处理器指令为变量 ppval 求值。因为 ppval 是一个预处理器变量,而不是常规的 PL/SQL 变量,所以使用 $$ 标志来指定它。同样,为了编译器能分辨自己只需在编译期间处理这些行,你要用特殊的 $ 标志来指定求值项,例如用 $if 代替 if。现在,利用变量 ppval 的不同值来编译这个函数。

SQL> alter session set plsql_ccflags = 'PPVAL:TRUE';

Session altered.

现在编译该函数并执行它。

SQL> alter function myfunc compile;

Function altered.

SQL> select myfunc from dual;

MYFUNC

-------------------------------------

PPVAL was TRUE

在编译期间 ppval 的值被设为 false。现在更改该变量的值并重新执行该函数。

SQL> alter session set plsql_ccflags = 'PPVAL:FALSE';

Session altered.

SQL> select myfunc from dual;

MYFUNC

---------------------------------------------------------

PPVAL was TRUE

虽然这里 ppval 的值在会话中是 FALSE,但函数没有采用它;而是采用了在编译期间所设置的值。现在,重新编译该函数并执行它。

SQL> alter function myfunc compile;

Function altered.

SQL> select myfunc from dual;

MYFUNC

---------------------------------------------------

PPVAL was FALSE

在编译期间,ppval 的值是 FALSE,而这就是所返回的值。

#自适应游标:

因此,如您所见,尽管绑定变量在大多数情况下都非常有效,当值的选择性将显著影响计划时(正如在此示例中,值 'CT' 和 'NY' 的选择性分别为 5% 和 95%),绑定变量并不可靠。如果数据分布均匀,所有值的选择性几乎相同,执行计划将保持不便。因此,聪明的 SQL 编码人员将会选择在何时打破使用绑定变量的基本准则,改用文字值。

select is_bind_sensitive, is_bind_aware, sql_id, child_number

from v$sql

where sql_text = 'select count(1) from customers where state_code = :state_code and times_purchased > 3'

I I SQL_ID CHILD_NUMBER

- - ------------- ------------

Y Y 7cv5271zx2ttg 0

Y N 7cv5271zx2ttg 1

让我们看一看这些列的含义。Oracle 对游标进行观察,并确定值变化的方式。如果不同的值可能会改变计划,则游标标记为 "Bind-Sensitive",IS_BIND_SENSITIVE 列显示 "Y"。在几次执行后,数据库对游标和值有了更多了解,并确定游标是否应根据值的变化来改变计划。如果情况如此,则游标被称为 "Bind-Aware",IS_BIND_AWARE 列显示 "Y"。总结:Bind-Sensitive 游标是可能会更改计划的游标,而 Bind-Aware 游标是实际更改计划的游标。

由于自适应游标共享特性根据绑定变量的值使用正确的计划,数据库必须在某处存储这些信息。它通过另一个新视图 V$SQL_CS_SELECTIVITY 显示这些信息,该视图显示传递给绑定变量的不同值的选择性。

select * from v$sql_cs_selectivity

视图显示了大量信息。PREDICATE 列显示了用户使用的各种谓词(WHERE 条件)。LOW 和 HIGH 值显示传递的值的范围。

最后,第三个新视图 V$SQL_CS_STATISTICS 显示了标记为 Bind-Aware 或 Bind-Sensitive 的游标执行的操作。

#复合触发器

我们的系统用不到

create or replace trigger tr_bookings_track

for update of booking_dt on bookings

compound trigger

type ty_bookings_hist is table of bookings_hist%rowtype index by pls_integer;

coll_bookings_hist ty_bookings_hist;

ctr pls_integer := 0;

--------------------------------------------------------------

before statement is

begin

dbms_output.put_line('In before statement');

end before statement;

----------------------------------------------------------------

before each row is

begin

dbms_output.put_line('In before each row');

end before each row;

-------------------------------------------------------------------

after each row is

begin

ctr := ctr + 1;

dbms_output.put_line('In after each row. booking_id=' || :new.booking_id);

coll_bookings_hist(ctr).booking_id := :new.booking_id;

coll_bookings_hist(ctr).mod_dt := sysdate;

coll_bookings_hist(ctr).mod_user := user;

coll_bookings_hist(ctr).old_booking_dt := :old.booking_dt;

coll_bookings_hist(ctr).new_booking_dt := :new.booking_dt;

end after each row;

--------------------------------------------------------------------

after statement is

begin

dbms_output.put_line('In after statement');

forall counter in 1 .. coll_bookings_hist.count()

insert into bookings_hist values coll_bookings_hist(counter);

end after statement;

--------------------------------------------------------------------

end tr_bookings_track;

/

create or replace trigger tr_pay_follow_up

before update

on payments

for each row

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/9879835/viewspace-1020731/ ,如需转载,请注明出处,否则将追究法律责任。

上一篇: 启动 HP-UX 系统
下一篇: 数据泵用法笔记
请登录后发表评论 登录
全部评论

注册时间:2011-05-25

  • 博文量
    109
  • 访问量
    1577023