| Windows下采用处理spool数据并用WinRAR压缩的一个DEMO |
作者 tomszrp 18:55 |
静态链接网址 |
最新回复 (3) |
引用 (0) |
磨刀石 |
|
源至一个puber的需求:要spool一些数据出来,并自动实现压缩功能 要实现这个目的,需要具备如下几个条件 1)安装并配置了WinRAR,设置相应的path,否则可能遇到找不到Rar.exe文件的错误 比如:set PATH=%PATH%;C:Program FilesWinRAR 2)编写实现spool 数据的SQL脚本,比如 mysql.sql内容类似如下: spool e:test.txt select sysdate from dual; spool off exit #具体的SQL内容要根据自己的需要做相应的调整 3)编写bat文件,比如mybat.bat 内容类似如下: sqlplus study/study@ora10g @e:mysql.sql Rar a e:my.rar e:test.txt del e:test.txt
#具体的bat内容根据实际的实际情况做相应的调整 最后就可以调用mybat.bat达到自己的目的了,测试如下: E:>set PATH=%PATH%;C:Program FilesWinRAR E:>mybat.bat E:>sqlplus study/study@ora10g @e:mysql.sql SQL*Plus: Release 10.2.0.2.0 - Production on Mon May 19 18:40:48 2008 Copyright (c) 1982, 2005, Oracle. All Rights Reserved. Connected to: Oracle Database 10g Enterprise Edition Release 10.2.0.2.0 - Production With the Partitioning, OLAP and Data Mining options
SYSDATE ------------ 19-MAY-08
Disconnected from Oracle Database 10g Enterprise Edition Release 10.2.0.2.0 - Pr oduction With the Partitioning, OLAP and Data Mining options E:>Rar a e:my.rar e:test.txt RAR 3.71 版权 (C) 1993-2007 Alexander Roshal 20 九月 2007 共享版本 输入 RAR -? 获得帮助 评估版本,请注册 正在创建 压缩文件 e:my.rar 正在添加 e:test.txt 完成 完成 E:>del e:test.txt E:>dir my.rar 驱动器 E 中的卷是 工作盘 卷的序列号是 3C1B-44A4 E: 的目录 2008-05-19 18:40 125 my.rar 1 个文件 125 字节 0 个目录 30,395,387,904 可用字节 E:>
|
| 遭遇memory leak bug |
作者 tomszrp 17:30 |
静态链接网址 |
最新回复 (0) |
引用 (0) |
磨刀石 |
操作系统aix 5305,Oracle 10.2.0.2
Bug: 5548510
REPORTED: 10.2.0.2
FIXED:10.2.0.4 and 11.x
NOTES:Backports Available CBO leak.
DETAILS: The allocation in the SGA for fix control will grow with each new session.
You will see this running: select * from v$sgastat where name like 'qksbg%'.
SQL> select * from v$sgastat where pool='shared pool' order by bytes;
POOL NAME BYTES
------------ -------------------------- ----------
shared pool kscdnfyglobalflags 8
shared pool qksbgsg 8
shared pool kscdnfyinitflags 8
......
shared pool KGLS heap 36760288
shared pool PCursor 44117240
shared pool library cache 48749632
shared pool CCursor 71147656
shared pool sql area 295314376
shared pool free memory 323258728
shared pool qksbgCreateSessionEnv:qks 2422252024
590 rows selected.
SQL>
各种状态chunk的分布:
CLASS NUM SIZ AVG SIZE
-------- ---------- ---------- ------------
R-freea 410 19680 .05k
freeabl 203754 403504152 1.93k
recr 131365 143609304 1.07k
R-free 205 309804200 1,475.82k
perm 63556 2582330752 39.68k
free 3 43152 14.05k
其中perm一项不停的涨,最终会导致ORA-04031出现.
TNND,折磨死了,没有服务的Oracle Support很不好搞啊!
|
| 手工删除和重建10g db control |
作者 tomszrp 18:35 |
静态链接网址 |
最新回复 (0) |
引用 (0) |
磨刀石 |
|
本文仅仅是一个测试操作的笔记,不作为大家日常管理的行为指南,希望不要误导大家。 ^|^ Microsoft Windows XP [版本 5.1.2600] (C) 版权所有 1985-2001 Microsoft Corp. C:Documents and SettingsAdministrator>set ORACLE_SID=ora10g C:Documents and SettingsAdministrator>set ORACLE_HOME=c:oracle10g C:Documents and SettingsAdministrator>emca -deconfig dbcontrol db EMCA 开始于 2008-5-11 17:33:26 EM Configuration Assistant, 10.2.0.1.0 正式版 版权所有 (c) 2003, 2005, Oracle。保留所有权利。 输入以下信息: 数据库 SID: ora10g 是否继续? [yes(Y)/no(N)]: yes 2008-5-11 17:33:33 oracle.sysman.emcp.EMConfig perform 信息: 正在将此操作记录到 C:oracle10gcfgtoollogsemcaora10gemca_2008-05-11_05 -33-25-下午.log。 2008-5-11 17:33:34 oracle.sysman.emcp.util.DBControlUtil stopOMS 信息: 正在停止 Database Control (此操作可能需要一段时间)... 已成功完成 Enterprise Manager 的配置 EMCA 结束于 2008-5-11 17:34:05 C:>cd c:oracle10gsysmanadminemdrepbin
C:oracle10gsysmanadminemdrepbin>dir 驱动器 C 中的卷是 系统盘 卷的序列号是 1C8B-7331 C:oracle10gsysmanadminemdrepbin 的目录 2008-01-29 21:29 <DIR> . 2008-01-29 21:29 <DIR> .. 2005-05-12 08:43 557 ConfirmEMDDown.xml 2005-05-12 10:39 65,759 emrepmgr.pl 2005-05-12 10:39 1,746 RepManager.bat 3 个文件 68,062 字节 2 个目录 11,067,408,384 可用字节 C:oracle10gsysmanadminemdrepbin>repmanager localhost 1523 ora10g -action drop Enter SYS user's password :sysadmin Enter repository user name : sysman Enter repository user password : sysadmin Getting temporary tablespace from database... Found temporary tablespace: TEMP Checking SYS Credentials ... OK. Dropping the repository.. Quiescing DB ... Done. Checking for Repos User ... Exists. Repos User exists.. Clearing EM Contexts ... OK. Dropping EM users ... Done. Dropping Repos User ... Done. Dropping Roles/Synonymns/Tablespaces ... Done. Unquiescing DB ... Done. Dropped Repository Successfully. C:oracle10gsysmanadminemdrepbin> C:oracle10gsysmanadminemdrepbin> C:oracle10gsysmanadminemdrepbin>
C:oracle10gsysmanadminemdrepbin>emca -config dbcontrol db -repos create
EMCA 开始于 2008-5-11 17:45:50 EM Configuration Assistant, 10.2.0.1.0 正式版 版权所有 (c) 2003, 2005, Oracle。保留所有权利。 输入以下信息: 数据库 SID: ora10g 监听程序端口号: 1523 SYS 用户的口令: DBSNMP 用户的口令: SYSMAN 用户的口令: 通知的电子邮件地址 (可选): 通知的发件 (SMTP) 服务器 (可选): ----------------------------------------------------------------- 已指定以下设置 数据库 ORACLE_HOME ................ C:oracle10g 数据库主机名 ................ localhost 监听程序端口号 ................ 1523 数据库 SID ................ ora10g 通知的电子邮件地址 ............... 通知的发件 (SMTP) 服务器 ............... ----------------------------------------------------------------- 是否继续? [yes(Y)/no(N)]: yes 2008-5-11 17:46:23 oracle.sysman.emcp.EMConfig perform 信息: 正在将此操作记录到 C:oracle10gcfgtoollogsemcaora10gemca_2008-05-11_05-45-50-下午.log。 2008-5-11 17:46:27 oracle.sysman.emcp.EMReposConfig createRepository 信息: 正在创建 EM 资料档案库 (此操作可能需要一段时间)... 2008-5-11 17:53:46 oracle.sysman.emcp.EMReposConfig invoke 信息: 已成功创建资料档案库 2008-5-11 17:54:06 oracle.sysman.emcp.util.DBControlUtil startOMS 信息: 正在启动 Database Control (此操作可能需要一段时间)... 2008-5-11 17:54:57 oracle.sysman.emcp.EMDBPostConfig performConfiguration 信息: 已成功启动 Database Control 2008-5-11 17:54:57 oracle.sysman.emcp.EMDBPostConfig performConfiguration 警告: 无法创建 Database Control 快捷方式 2008-5-11 17:54:57 oracle.sysman.emcp.EMDBPostConfig performConfiguration 信息: >>>>>>>>>>> Database Control URL 为 http://localhost:1158/em <<<<<<<<<<< 已成功完成 Enterprise Manager 的配置 EMCA 结束于 2008-5-11 17:54:57 C:oracle10gsysmanadminemdrepbin>emctl status dbconsole Oracle Enterprise Manager 10g Database Control Release 10.2.0.2.0 Copyright (c) 1996, 2005 Oracle Corporation. All rights reserved. http://localhost:1158/em/console/aboutApplication Oracle Enterprise Manager 10g is running. ------------------------------------------------------------------ Logs are generated in directory C:oracle10g/localhost_ora10g/sysman/log C:oracle10gsysmanadminemdrepbin>
|
| 修改Oracle 10g EM DB Control port的方法 |
作者 tomszrp 18:38 |
静态链接网址 |
最新回复 (5) |
引用 (0) |
磨刀石 |
1)emctl stop dbconsole 2)vi $ORACLE_HOME/hostname_SID/sysman/config/emoms.properties 修改: oracle.sysman.emSDK.svlt.ConsoleServerPort oracle.sysman.emSDK.svlt.ConsoleServerHTTPSPort 3)vi $ORACLE_HOME/hostname_SID/sysman/config/emd.properties 修改: REPOSITORY_URL emdWalletSrcUrl 4)vi $ORACLE_HOME/oc4j/j2ee/OC4J_DBConsole_hostname_SID/config/http-web-site.xml 修改 web-site port 5)emctl start dbconsole 6)http://hosname:new_port/em (test)
|
| GPFS简介 |
作者 tomszrp 09:13 |
静态链接网址 |
最新回复 (0) |
引用 (0) |
磨刀石 |
|
前言 GPFS(General Parallel File System)是IBM公司推出的行业领先的并行分布式通用并行集群文件系统,GPFS从1993开始研发,1995年投入商用(最早投入使用在多媒体处理行业,所以我们现在看到GPFS的很多目录和命令为什么都有MM[multimedia]两个字母,就是根据这个背景延续下来的),其中经过了多次版本的改进和修订,到目前(2008),GPFS的当前版本为3.1. GPFS是一个共享的磁盘文件系统,集群内的所有节点(NODE)可以并行的访问所有共享磁盘,并通过分布式的令牌管理机制和条带化技术来管理和优化各个节点的访问。 GPFS的应用范围非常广泛,从多节点的文件共享服务到大型的高性能计算机群,都可以看到GPFS的优秀表现。GPFS也应用在众多的企业应用系统中,比如高可用的解决方案:HACMP,ORACLE RAC,SAP的共享文件系统等,GPFS在这些应用里面都表现出了出色的性能和高可用性 什么是GPFS GPFS(General Parallel File System)是通用并行文件系统的缩写。 GPFS是一种高性能的、共享磁盘的、分布式文件系统 高性能:GPFS可以支持1个到上千个独立的计算机节点 可以从单个节点管理整个文件 支持AIX,LINUX以及混合节点环境 共享磁盘:所有的磁盘可以被所有的节点同等的访问 数据和元数据对节点的访问是相同的 任何直连节点都可以对任何磁盘进行读写 分布式:数据和元数据可以被任何一个节点来处理 所有节点都不需要经由其他节点就可以直接处理数据和元数据 消除了单一节点故障 tips:GPFS在内部采用了分布式的token的管理,通过token manger Server的功能来统一的对数据访问进行授权,对数据的授权可以做到数据块一级。可以保证多个节点对同一个文件进行修改。 查看全文
|
| 疯狂宕机的一周 |
作者 tomszrp 20:34 |
静态链接网址 |
最新回复 (0) |
引用 (0) |
磨刀石 |
|
周一到周三连续三天3套HA纷纷罢工,周四系统消停了一下,周五再宕,周六网络不干了,5台Server 网卡down,其中一台直接影响到生产,周六把其中一个影响生产的network cable更换后,系统正常,但周日另外一个又不行了,TNND,这就是使用劣质产品的后果. 没办法,该换的还是全换吧(早干啥去了?) 这是我这么多年来遇到的超疯狂的现象.....
|
| 如何在Exception Block中捕获异常发生所在行 |
作者 tomszrp 11:43 |
静态链接网址 |
最新回复 (0) |
引用 (0) |
磨刀石 |
|
在这篇小技巧中,介绍一下如何在Exception Block中捕获错误发生的所在行,以便于我们准确的定位和解决问题。在实际的pl/sql开发过程中,有的pl/sql代码非常庞大,甚至彼此嵌套了好多层,当然了,Exception部分也就变的复杂起来。 这个时候,我们在日常运维或开发调试的时候,经常会根据Exception Block中抛出的raise去分析是程序的问题还是数据的问题,以便于后期改进和处理。那么有的人就很头疼,一组上K行的pl/sql,分析起来也是很头疼的,他们就希望能在出现异常的时候,知道准确的出错SQL所在行。 以前我们一般就简单的通过SQLCODE、SQLERRM来获取一些错误代码和相关的信息,从Oralce 9开始,我们可以借助DBMS_UTILITY.FORMAT_ERROR_BACKTRACE() 函数来实现我们的目标。 下面我通过一个简单的DEMO来说一下如何调用这个函数: conn study/study;
create table zrp (no int);
set serveroutput on
declare
v_no number;
begin
select no into v_no from zrp;
exception
when others then
dbms_output.put_line('SQL CODE:'||sqlcode||chr(10)||
sqlerrm||chr(10)||
dbms_utility.format_error_backtrace());
end;
/
测试一下看看: SQL> declare
2 v_no number;
3 begin
4 select no into v_no from zrp;
5 exception
6 when others then
7 dbms_output.put_line('SQL CODE:'||sqlcode||chr(10)||
8 sqlerrm||chr(10)||
9 dbms_utility.format_error_backtrace());
10 end;
11 /
SQL CODE:100
ORA-01403: no data found
ORA-06512: at line 4
PL/SQL procedure successfully completed
SQL> 是不是很好用?
|
| 如何通过SQL*Plus在命令行传入参数调用过程 |
作者 tomszrp 20:22 |
静态链接网址 |
最新回复 (0) |
引用 (0) |
磨刀石 |
|
在实际的业务系统维护的过程中或日常管理过程中,我们经常需要在command下调用脚本来完成一些工作,其中有的时候又需要在command中去传递一些变量到procedure中,那么如何实现呢? 一般常见的做法是大家写一个简单的shell脚本或bat脚本,再调用sqlplus 直接通过&var_name即可传入实现。 今天我再介绍另外一个实现的思路,我想很多人一定都写过: 先建立一个表和过程 create table test(no_in int,no_out int);
create or replace procedure proc_test (p_1 in number) is
begin
insert into test values(p_1,p_1*2);
commit;
end;
/ 过程proc_test代表我要完成的工作。 然后写一个调用该过程来完成工作的SQL set echo off feedback off verify off pagesize 100
variable x number
begin
:x := &1;
end;
/
execute proc_test(:x)
select * from test;
exit
最后我们在command 下执行该脚本: C:>sqlplus -s study/study @test.sql 100
NO_IN NO_OUT
---------- ----------
100 200
C:>
当然,我们也可以在sqlplus中调用这个test.sql,比如(记得去掉前面test.sql中最后的exit,否则一执行完就关闭窗口了)
SQL> start c:test.sql 200
NO_IN NO_OUT
---------- ----------
100 200
200 400
SQL>
是不是很好用?不要小看他,或许将来某一个你就需要类似的写法去完成一个task了。
|
| 关于DBA_USERS视图中ACCOUNT_STATUS 列的各种取值的含义说明 |
作者 tomszrp 18:43 |
静态链接网址 |
最新回复 (0) |
引用 (0) |
磨刀石 |
SQL> select * from sys.user_astatus_map;
STATUS# STATUS
---------- --------------------------------
0 OPEN
1 EXPIRED
2 EXPIRED(GRACE)
4 LOCKED(TIMED)
8 LOCKED
5 EXPIRED & LOCKED(TIMED)
6 EXPIRED(GRACE) & LOCKED(TIMED)
9 EXPIRED & LOCKED
10 EXPIRED(GRACE) & LOCKED
9 rows selected
通过上面的查询我们可以看到在Oracle中accunt总共有9种不同的状态,对应dba_users视图中的account_status字段。下面我分别就每种状态的含义和出现的情况做个简单的说明,以便于今后的系统管理和维护。 分析上面的9种状态不难看出,其实独立的状态只有OPEN、EXPIRED、LOCKED、EXPIRED(GRACE)、LOCKED(TIMED) 5种形式。其他4种不过是前面几种形式的组合而已。 OPEN: 这个是大家最常见的,就是表示这个是可用的,没有任何限制的帐户 LOCKED:表示这个帐户被DBA锁定. 一般通过alter user username account lock(unlock); EXPIRED:表示该帐户被设置为口令到期,要求用户在下次logon的时候修改口令(系统会在该account被设置为expire后的第一次登陆是提示你修改密码) EXPIRED(GRACE):当设置了grace以后(第一次成功登录后到口令到期后有多少天时间可改变口令,在这段时间内,帐户被提醒修改口令并可以正常登陆,account_status显示为EXPIRED(GRACE). LOCKED(TIMED):这种状态表示失败的login次数超过了FAILED_LOGIN_ATTEMPTS,被系统自动锁定,需要注意的是,在Oracle 10g中,默认的DEFAULT值是10次. 剩下的几种情况就是上面的组合了: EXPIRED & LOCKED SQL> alter user study password expire account lock; 用户已更改。
SQL> select account_status from dba_users where username='STUDY';
ACCOUNT_STATUS -------------------------------- EXPIRED & LOCKED
SQL> EXPIRED(GRACE) & LOCKED(TIMED)当account_stutus为EXPIRED(GRACE)的时候,用户又失败的login次数超过了FAILED_LOGIN_ATTEMPTS,被系统自动锁定
EXPIRED & LOCKED(TIMED)当设置了account expire后,用户又失败的login次数超过了FAILED_LOGIN_ATTEMPTS,被系统自动锁定
EXPIRED(GRACE) & LOCKED用户account_status为EXPIRED(GRACE)后,又被DBA 手工锁定帐户后的状态。
|
| 手动安装卸栽Oracle text on 10gR2 |
作者 tomszrp 16:32 |
静态链接网址 |
最新回复 (0) |
引用 (0) |
磨刀石 |
|
这两天周末没事,对Oracle text发生了兴趣(之前一直没实际用过,也没太花时间关注过).找到了《Oracle 10gR2 text Reference》后,想测试玩玩,结果发现我的系统中没有装这部分东西(因为我是手工建的库,如果通过Database Configuration Assistant (DBCA建库的话,text就默认被安装了) Oracle Text is available for no extra Licensing in all four database editions: Oracle Database Standard Edition One, Oracle Database Standard Edition (SE), Oracle Database Enterprise Edition (EE) Oracle Database Personal Edition. 安装的过程比较简单 Note: In SQL*Plus we use '?' instead of $ORACLE_HOME 1. Text dictionary, schema name CTXSYS, is created by calling following script from SQL*Plus connected as SYSDBA: SQL> conn /as sysdba; SQL> spool setup_info.txt SQL> start ?/ctx/admin/catctx.sql CTXSYS SYSAUX TEMP NOLOCK; Where: CTXSYS - is the ctxsys user password SYSAUX - is the default tablespace for ctxsys TEMP - is the temporary tablespace for ctxsys LOCK|NOLOCK - ctxsys user account will be locked or not 2. The next step is to install appropriate language-specific default preferences. There is script which creates language-specific default preferences for every language Oracle text supports in /ctx/admin/defaults directory, such as English(US), Danish(DK), Dutch(NL), Finnish(SF), French(F), German(D), Italian(IT), Portuguese(PT), Spanish(E), and Swedish(S). They are named in the form drdefXX.sql, where XX is the international license plate code. To manually install US default preferences, for example, log into sqlplus as CTXSYS, and run 'drdefus.sql' as described below: SQL> conn CTXSYS/CTXSYS; SQL> start ?/ctx/admin/defaults/drdefus.sql SQL> spool off 安装完了以后在做个简单的检查 SQL> -- check on setup SQL> select comp_name, status, substr(version,1,10) as version 2 from dba_registry 3 where comp_id = 'CONTEXT';
COMP_NAME STATUS VERSION ---------------- ---------------------- ----------- Oracle Text VALID 10.2.0.2.0 SQL> select * from ctxsys.ctx_version; VER_DICT VER_CODE ---------- --------------- 10.2.0.2.0 10.2.0.2.0 SQL> select substr(ctxsys.dri_version,1,10) VER_CODE from dual; VER_CODE ------------- 10.2.0.2.0 SQL> select count(*) from dba_objects where owner='CTXSYS'; COUNT(*) ---------- 339 SQL> -- Get a summary count SQL> select object_type, count(*) from dba_objects where owner='CTXSYS' group by object_type; OBJECT_TYPE COUNT(*) ------------------- ---------- SEQUENCE 3 PROCEDURE 2 OPERATOR 6 LIBRARY 1 PACKAGE 71 PACKAGE BODY 58 LOB 1 TYPE BODY 7 FUNCTION 5 VIEW 54 TABLE 37 INDEX 46 INDEXTYPE 4 TYPE 44 14 rows selected SQL> -- Any invalid objects SQL> select object_name, object_type, status 2 from dba_objects 3 where owner='CTXSYS' and status != 'VALID' order by object_name; OBJECT_NAME OBJECT_TYPE STATUS ---------------- ------------------- ------- SQL> 如果要卸载Oracle text的话,调用另外的脚本即可完成: SQL> start ?/ctx/admin/catnoctx.sql; 动作比较简单,但我之前没有接触过,所以还是不知道,通过今天的研究,才算对这部分东西入了门。 关于Oracle text的详细资料,可以参考Part Number B14218-01.
|
| 设置基于Column - Level 的VPD |
作者 tomszrp 16:04 |
静态链接网址 |
最新回复 (0) |
引用 (0) |
磨刀石 |
|
上一篇文章介绍了row-based VPD,这节给出一个column-level VPD的简单demo. 从Oracle 10g开始,我们可以设置基于column-level的VPD,从而保护那些资料表中的重要信息列,比如password column、Price等(这个要根据具体的应用需求来定),有两种column-level的方法可以使用: 1)使用column-level VPD 保护数据不被访问 2)Display the column with NULL values 说明:1)一个查询中包含被保护的column 2)和基于row-based VPD有所不同,在column-level VPD中,所有的行均可以被访问,但是被保护列可以被隔离或采用MASK显示。 3)column-level VPD在表和视图上均可设置 实现:和row-based VPD相似,我们只需在调用dbms_rls.add_policy的时候,指定sec_relevant_cols(指定被保护列),sec_relevant_cols_opt(MASK)两个参数即可. 下面我通过一个test case来简单的介绍一下,关于更详尽的用法,请参考Oracle官方手册。 需求说明: 对于study.customer 表中的status 字段,不允许维护帐户(user_a,user_b)查看或显示为NULL。 实现过程 1)创建测试表、用户,并授予相应的权限 --建表 create table study.customer ( region varchar2(4), msisdn varchar2(11), status varchar2(2) ); --插入数据 insert into study.customer values('530','13905301234','0'); insert into study.customer values('530','13905305678','1'); insert into study.customer values('531','13805318888','0'); insert into study.customer values('531','13605319999','1'); insert into study.customer values('532','15805320000','0'); insert into study.customer values('533','15905336666','0'); commit;
--授权 create user user_a identified by user_a default tablespace data_01; create user user_b identified by user_b default tablespace data_01;
grant create session to user_a,user_b;
grant select,insert,update,delete on study.customer to user_a,user_b; grant execute on dbms_rls to user_a,user_b; 2)创建一个security package,并授权 create or replace package study.security_pkg as function test_security(owner varchar2,objname varchar2) return varchar2; end; / create or replace package body study.security_pkg is function test_security(owner varchar2,objname varchar2) return varchar2 is v_sql varchar2(2000):='1=0'; begin if (sys_context('USERENV','SESSION_USER') ='STUDY') then v_sql:=null; end if; return v_sql; end; end; / grant execute on study.security_pkg to public; create or replace public synonym security_pkg for study.security_pkg;
3)设置policy begin dbms_rls.add_policy( object_schema => 'STUDY', object_name => 'CUSTOMER', policy_name => 'C_COL_POLICY', function_schema => 'STUDY', policy_function => 'SECURITY_PKG.TEST_SECURITY', sec_relevant_cols => 'STATUS'); end; / --在这个security policy 设置中,我们指定了status列是被保护的列,所有的维护帐户不能访问该列,否则将返回0行。 4)测试column-level VPD 下面我们来感受一下吧(user_a,user_b是受限的维护帐户,看看效果) SQL> conn user_a/user_a
已连接。
SQL> select * from study.customer;
未选定行
SQL> select region,msisdn from study.customer;
REGI MSISDN
---- -----------
530 13905301234
530 13905305678
531 13805318888
531 13605319999
532 15805320000
533 15905336666
已选择6行。
SQL> select msisdn,status from study.customer;
未选定行
SQL> conn user_b/user_b
已连接。
SQL> select * from study.customer;
未选定行
SQL> select region,msisdn from study.customer;
REGI MSISDN
---- -----------
530 13905301234
530 13905305678
531 13805318888
531 13605319999
532 15805320000
533 15905336666
已选择6行。
SQL> select msisdn,status from study.customer;
未选定行
SQL> conn study/study
已连接。
SQL> select * from study.customer;
REGI MSISDN ST
---- ----------- --
530 13905301234 0
530 13905305678 1
531 13805318888 0
531 13605319999 1
532 15805320000 0
533 15905336666 0
已选择6行。
SQL> select msisdn,status from study.customer;
MSISDN ST
----------- --
13905301234 0
13905305678 1
13805318888 0
13605319999 1
15805320000 0
15905336666 0
已选择6行。
SQL>
5)补充说明 一、如果要保护多列,我们只需要在sec_relevant_cols参数中指定多个列即可(用,分开),比如 begin
dbms_rls.add_policy(
object_schema => 'STUDY',
object_name => 'CUSTOMER',
policy_name => 'C_COL_POLICY',
function_schema => 'STUDY',
policy_function => 'SECURITY_PKG.TEST_SECURITY',
sec_relevant_cols => 'MSISDN,STATUS');
end;
/
二、如果要采用masking option,我们只需要在设置policy的时候,指定sec_relevant_cols_opt 参数为DBMS_RLS.ALL_ROWS即可,比如:begin
dbms_rls.add_policy(
object_schema => 'STUDY',
object_name => 'CUSTOMER',
policy_name => 'C_COL_POLICY',
function_schema => 'STUDY',
policy_function => 'SECURITY_PKG.TEST_SECURITY',
sec_relevant_cols => 'STATUS',
sec_relevant_cols_opt => dbms_rls.all_rows);
end;
/
在这种保护模式下,被保护的列,均显示是NULL。 三、同样的如果我们需要保护涉及到该列的DML操作时,需要设置如下2个参数(前面的row-based VPD中已经介绍过了) begin
dbms_rls.add_policy(
object_schema => 'STUDY',
object_name => 'CUSTOMER',
policy_name => 'C_COL_POLICY',
function_schema => 'STUDY',
policy_function => 'SECURITY_PKG.TEST_SECURITY',
statement_types => 'SELECT,INSERT,UPDATE,DELETE',
update_check => TRUE,
sec_relevant_cols => 'STATUS');
end;
/
四、masking option只支持查询操作,对DML操作无效 五、捎带说一下 如果要删除一个policy,可以通过dbms_rls.drop_policy完成,如 begin dbms_rls.drop_policy (object_schema => 'STUDY', object_name => 'CUSTOMER', policy_name => 'C_COL_POLICY'); end; / 如果要enable/disable一个policy可以通过dbms_rls.enable_policy完成,如 SQL> exec dbms_rls.enable_policy('STUDY','CUSTOMER','C_COL_POLICY',FALSE); PL/SQL procedure successfully completed
SQL> exec dbms_rls.enable_policy('STUDY','CUSTOMER','C_COL_POLICY',TRUE);
PL/SQL procedure successfully completed
SQL> 好了,这节就到这里了。
|
| 利用vpd实现security policy to tables |
作者 tomszrp 12:32 |
静态链接网址 |
最新回复 (0) |
引用 (0) |
磨刀石 |
|
VPD的概念,大家应该都比较清楚(本文不做具体的介绍),今天在针对一个具体的case配置了一个vpd policy,下面把概要的测试过程简单的show一下,详细的技术细节,大家要参阅Oracle DOC. 场景模拟 比如实际的应用中有这样的需求: 系统中有user_a,user_b,usre_c,user_d,user_e 5个维护帐户,其中: user_name user_region --------------- ---------------- user_a 530 user_b 530 user_c 531 user_d 532 user_e 532
系统中所有的table(study schema下)中都有region这样的字段,但我们限制这些维护帐户只能select所属region的记录(比如采用了FGA,VPD策略),那么我们就可以设置一个简单的上下文环境来替换每次不必要的table join或app定制的工作。 比如:select * from study.customer where region=sys_context('TEST_CONTEXT','USER_REGION'); 备注:如果配置了vpd,这个SQL就可以简单的变为:select * from study.customer; 环境准备 *study 用户我已经提前创建 1)在study用户下创建一张帐户信息表和资料表 --帐户表 create table study.account_def ( user_name varchar2(30), user_region varchar2(4) ) tablespace data_01; --插入帐户信息 insert into study.account_def values('USER_A','530'); insert into study.account_def values('USER_B','530'); insert into study.account_def values('USER_C','531'); insert into study.account_def values('USER_D','532'); insert into study.account_def values('USER_E','532'); commit; --资料表 create table study.customer ( region varchar2(4), msisdn varchar2(11), status varchar2(2) ); --插入一些信息模拟用户资料 insert into study.customer values('530','13905301234','0'); insert into study.customer values('530','13905305678','1'); insert into study.customer values('531','13805318888','0'); insert into study.customer values('531','13605319999','1'); insert into study.customer values('532','15805320000','0'); insert into study.customer values('533','15905336666','0'); commit; 2)创建维护帐户并授予相应的访问权限 create user user_a identified by user_a default tablespace data_01; create user user_b identified by user_b default tablespace data_01; create user user_c identified by user_c default tablespace data_01; create user user_d identified by user_d default tablespace data_01; create user user_e identified by user_e default tablespace data_01; grant create session to user_a,user_b,user_c,user_d,user_e; grant select,insert,update,delete on study.customer to user_a,user_b,user_c,user_d,user_e; grant execute on dbms_rls to user_a,user_b,user_c,user_d,user_e; Create an Application Context 1)创建一个package create or replace package context_package is procedure set_context; end; /
create or replace package body context_package is procedure set_context is v_region varchar2(4); begin dbms_session.set_context('TEST_CONTEXT','SETUP','TRUE'); begin select user_region into v_region from account_def where user_name=USER; dbms_session.set_context('TEST_CONTEXT','USER_REGION',v_region); exception when OTHERS then dbms_session.set_context('TEST_CONTEXT','USER_REGION',0); end; dbms_session.set_context('TEST_CONTEXT','SETUP','FALSE'); end; end; / 2)将context_package授权到public并创建一个public synonym grant execute on study.context_package to public; create or replace public synonym context_package for study.context_package; 3)Create context create context test_context using study.context_package; Create a Logon Trigger create or replace trigger sys.trig_set_context after logon on database begin context_package.set_context; end; / Create a Security Policy 1)创建一个Package create or replace package study.security_pkg as function test_security(owner varchar2,objname varchar2) return varchar2; end; / create or replace package body security_pkg is function test_security(owner varchar2,objname varchar2) return varchar2 is v_sql varchar2(2000):='1=0'; begin if (sys_context('USERENV','SESSION_USER') ='STUDY') then v_sql:=null; else v_sql:='REGION=to_char(sys_context(''TEST_CONTEXT'',''user_region''))'; end if; return v_sql; end; end; / grant execute on study.security_pkg to public; create or replace public synonym security_pkg for study.security_pkg;
2)Apply The Security Policy to table begin dbms_rls.add_policy('STUDY','CUSTOMER','C_SELECT_POLICY', 'STUDY','SECURITY_PKG.SELECT_SECURITY','SELECT',true); end; / Test VPD Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.2.0
Connected as user_a
SQL> select sys_context('USERENV','SESSION_USER') username,
2 sys_context('TEST_CONTEXT','user_region') user_attr
3 from dual;
USERNAME USER_ATTR
--------------- -------------
USER_A 530
SQL> select * from study.customer;
REGION MSISDN STATUS
------ ----------- ------
530 13905301234 0
530 13905305678 1
SQL> insert into study.customer values('530','15805303333','9');
1 row inserted
SQL> insert into study.customer values('010','15801006666','9');
insert into study.customer values('010','15801006666','9')
ORA-28115: 策略违反检验选项
SQL> update study.customer set region='531' where region='530' and msisdn='15805303333' and status='9';
1 row updated
SQL> select * from study.customer;
REGION MSISDN STATUS
------ ----------- ------
530 13905301234 0
530 13905305678 1
SQL> delete from study.customer where region='531' and msisdn='15805303333' and status='9';
0 rows deleted
SQL> 其他测试内容,就不再多贴了。有兴趣的朋友可以自己测试一下.
最后一步:清理测试环境 conn /as sysdba begin dbms_rls.drop_policy (object_schema => 'STUDY', object_name => 'CUSTOMER', policy_name => 'C_SELECT_POLICY'); end; / drop table study.account_def purge; drop table study.customer purge; drop user user_a cascade; drop user user_b cascade; drop user user_c cascade; drop user user_d cascade; drop user user_e cascade; drop trigger sys.trig_set_context;
drop public synonym context_package; drop package study.context_package; drop public synonym security_pkg; drop package study.security_pkg; drop context test_context; (完)
|
| 相同的SQL不同的hash_value |
作者 tomszrp 21:19 |
静态链接网址 |
最新回复 (1) |
引用 (0) |
磨刀石 |
|
今天在分析SQL Shared问题的时候,无意中发现这个现象: 相同的SQL语句,在sqlplus,PL/SQL Developer的sql window和PL/SQL Developer command window下执行,居然得到不同的hash_value,自然这3个同样的SQL也就不能share了。 下面这个现象的再现过程: STUDY SQL> alter system flush shared_pool; 系统已更改。 STUDY SQL> create table zrp as select * from dba_tables; 表已创建。 session 1(sqlplus) STUDY SQL> select count(*) from zrp; COUNT(*) ---------- 1529 STUDY SQL> SQL> select '#'||sql_text||'#',sql_id,optimizer_mode,hash_value,address,plan_hash_value,module,action 2 from v$sqlarea 3 where sql_text like 'select count(*) from zrp%'; '#'||SQL_TEXT||'#' SQL_ID OPTIMIZER_MODE HASH_VALUE ADDRESS PLAN_HASH_VALUE MODULE ACTION ---------------------------- ------------- -------------- ---------- -------- --------------- ---------- ------------ #select count(*) from zrp# f1wuz71rax4ck ALL_ROWS 1856934290 6A553FE0 2384080583 SQL*Plus SQL> session 2(PL/SQL Developer的sql window) select count(*) from zrp; COUNT(*) ---------- 1529 SQL> select '#'||sql_text||'#',sql_id,optimizer_mode,hash_value,address,plan_hash_value,module,action 2 from v$sqlarea 3 where sql_text like 'select count(*) from zrp%'; '#'||SQL_TEXT||'#' SQL_ID OPTIMIZER_MODE HASH_VALUE ADDRESS PLAN_HASH_VALUE MODULE ACTION ----------------------------- ------------- -------------- ---------- -------- --------------- ----------------- -------------------- #select count(*) from zrp# f1wuz71rax4ck ALL_ROWS 1856934290 6A553FE0 2384080583 SQL*Plus #select count(*) from zrp # 52g7v6f6mpt7j ALL_ROWS 2369447153 6A69DDB0 2384080583 PL/SQL Developer SQL Window - New SQL> session 3(PL/SQL Developer command window) SQL> SQL> select count(*) from zrp; COUNT(*) ---------- 1529 SQL> select '#'||sql_text||'#',sql_id,optimizer_mode,hash_value,address,plan_hash_value,module,action 2 from v$sqlarea 3 where sql_text like 'select count(*) from zrp%'; '#'||SQL_TEXT||'#' SQL_ID OPTIMIZER_MODE HASH_VALUE ADDRESS PLAN_HASH_VALUE MODULE ACTION ------------------------------ ------------- -------------- ---------- -------- --------------- ------------------ -------------------- #select count(*) from zrp# f1wuz71rax4ck ALL_ROWS 1856934290 6A553FE0 2384080583 SQL*Plus #select count(*) from zrp # 52g7v6f6mpt7j ALL_ROWS 2369447153 6A69DDB0 2384080583 PL/SQL Developer SQL Window - New #select count(*) from zrp # 07fva4h7jj4p6 ALL_ROWS 253268646 6A4A9C9C 2384080583 PL/SQL Developer Command Window - New SQL> 通过上面对v$sqlarea的query 可以看到,实际是相同的SQL在执行的过程中,发生了变化,也就是传到Oracle去parse的 时候,并不完全是相同的SQL语句,在PL/SQL Developer SQL Window和PL/SQL Developer Command Window中分别在语句 的末尾增加了1个和2个空格.所以自然得到的hash_value不一样了。
|
| Oracle 11g Virtual Column-Based Partitioning |
作者 tomszrp 19:12 |
静态链接网址 |
最新回复 (0) |
引用 (0) |
磨刀石 |
|
摘录部分我的笔记的中doc,和大家一起感受Oracle 11g在分区方面的增强--基于虚拟列的分区 Virtual Column是11g中的一个新功能,这种列中的数据并不实际存储于磁盘上(可以看成是一个逻辑列或类似Function运算的列),只有当读取的时候才实时计算. 假设系统中有这样一张表 create table emp
( empno number(4),
sal number,
t_grade varchar2(1)
);
我们需要根据员工的薪水和技术等级来显示一下这些员工的分类,比如
sal t_grade t_class (实际不存在的列)
0 -2000 t_grade为any,则属于0段
2001 -5000 t_grade为C, 则属于1段
2001 -5000 t_grade为B, 则属于2段
2001 -5000 t_grade为A, 则属于3段
5001 -8000 t_grade为C, 则属于4段
5001 -8000 t_grade为B, 则属于5段
5001 -8000 t_grade为A, 则属于6段
8001 -15000 t_grade为C, 则属于7段
8001 -15000 t_grade为B, 则属于8段
8001 -15000 t_grade为A, 则属于9段
计划按照t_class列对该表进行分区,可实际上t_class列不存在,那怎么办呢.在11g之前,这个问题对DBA来说就束手无策了,而这一切,在11g中
迎刃而解。11g中新增加的虚拟列和虚拟列分区技术可以解决这个问题(详细的Virtual Column技术本案例中不做过多的介绍)
create table emp
( empno number(4),
sal number,
t_grade varchar2(1),
t_class number
as
(
case
when sal <= 2000 then 0
when sal > 2000 and sal <= 5000
then case
when t_grade='C' then 1
when t_grade='B' then 2
when t_grade='A' then 3
end
when sal > 5000 and sal <= 8000
then case
when t_grade='C' then 4
when t_grade='B' then 5
when t_grade='A' then 6
end
when sal > 8000
then case
when t_grade='C' then 7
when t_grade='B' then 8
when t_grade='A' then 9
else
10
end
end
)
)
partition by list (t_class)
(
partition p_0 values (0),
partition p_1 values (1),
partition p_2 values (2),
partition p_3 values (3),
partition p_4 values (4),
partition p_5 values (5),
partition p_6 values (6),
partition p_7 values (7),
partition p_8 values (8),
partition p_9 values (9),
partition p_10 values (10)
);
下面插入一些具体的值来看看 注意:对于使用了Virtual Column的表,在insert的时候,要么全部指定非Virtual Column, 要么对Virtual Column采用default值,如下面两种方式 insert into emp(empno,sal,t_grade) values(1001,1500,'C'); insert into emp values(1001,1500,'C',default); SQL> select table_name,partition_name,high_value,partition_position
2 from user_tab_partitions
3 where table_name='EMP'
4 order by partition_position;
TABLE_NAME PARTITION_NAME HIGH_VALUE PARTITION_POSITION
--------------- ----------------- ------------ ------------------
EMP P_0 0 1
EMP P_1 1 2
EMP P_2 2 3
EMP P_3 3 4
EMP P_4 4 5
EMP P_5 5 6
EMP P_6 6 7
EMP P_7 7 8
EMP P_8 8 9
EMP P_9 9 10
EMP P_10 10 11
11 rows selected
SQL>
insert into emp(empno,sal,t_grade) values(1001,1500,'C');
insert into emp(empno,sal,t_grade) values(1002,1500,'B');
insert into emp(empno,sal,t_grade) values(1003,1500,'A');
insert into emp(empno,sal,t_grade) values(1004,2500,'C');
insert into emp(empno,sal,t_grade) values(1005,3000,'B');
insert into emp(empno,sal,t_grade) values(1006,4500,'C');
insert into emp(empno,sal,t_grade) values(1007,6500,'C');
insert into emp(empno,sal,t_grade) values(1008,6500,'A');
insert into emp(empno,sal,t_grade) values(1009,7500,'C');
insert into emp(empno,sal,t_grade) values(1010,7000,'B');
insert into emp(empno,sal,t_grade) values(1011,8500,'C');
insert into emp(empno,sal,t_grade) values(1012,8500,'B');
insert into emp(empno,sal,t_grade) values(1013,8500,'A');
insert into emp(empno,sal,t_grade) values(1014,9500,'C');
insert into emp(empno,sal,t_grade) values(1015,10500,'B');
insert into emp(empno,sal,t_grade) values(1016,12000,'C');
insert into emp(empno,sal,t_grade) values(1017,12500,'B');
insert into emp(empno,sal,t_grade) values(1018,15000,'C');
commit;
SQL> select * from emp;
EMPNO SAL T_GRADE T_CLASS
----- ---------- ------- ----------
1001 1500 C 0
1002 1500 B 0
1003 1500 A 0
1004 2500 C 1
1006 4500 C 1
1005 3000 B 2
1007 6500 C 4
1009 7500 C 4
1010 7000 B 5
1008 6500 A 6
1011 8500 C 7
1014 9500 C 7
1016 12000 C 7
1018 15000 C 7
1012 8500 B 8
1015 10500 B 8
1017 12500 B 8
1013 8500 A 9
18 rows selected
SQL> select * from emp partition (p_0);
EMPNO SAL T_GRADE T_CLASS
----- ---------- ------- ----------
1001 1500 C 0
1002 1500 B 0
1003 1500 A 0
SQL> select * from emp partition (p_1);
EMPNO SAL T_GRADE T_CLASS
----- ---------- ------- ----------
1004 2500 C 1
1006 4500 C 1
SQL> select * from emp partition (p_2);
EMPNO SAL T_GRADE T_CLASS
----- ---------- ------- ----------
1005 3000 B 2
SQL> select * from emp partition (p_3);
EMPNO SAL T_GRADE T_CLASS
----- ---------- ------- ----------
SQL> select * from emp partition (p_4);
EMPNO SAL T_GRADE T_CLASS
----- ---------- ------- ----------
1007 6500 C 4
1009 7500 C 4
SQL> select * from emp partition (p_5);
EMPNO SAL T_GRADE T_CLASS
----- ---------- ------- ----------
1010 7000 B 5
SQL> select * from emp partition (p_6);
EMPNO SAL T_GRADE T_CLASS
----- ---------- ------- ----------
1008 6500 A 6
SQL> select * from emp partition (p_7);
EMPNO SAL T_GRADE T_CLASS
----- ---------- ------- ----------
1011 8500 C 7
1014 9500 C 7
1016 12000 C 7
1018 15000 C 7
SQL> select * from emp partition (p_8);
EMPNO SAL T_GRADE T_CLASS
----- ---------- ------- ----------
1012 8500 B 8
1015 10500 B 8
1017 12500 B 8
SQL> select * from emp partition (p_9);
EMPNO SAL T_GRADE T_CLASS
----- ---------- ------- ----------
1013 8500 A 9
SQL> select * from emp partition (p_10);
EMPNO SAL T_GRADE T_CLASS
----- ---------- ------- ----------
SQL>
说明:Partition pruning takes place for virtual column partition keys when the predicates on the partitioning key are of the following types: Equality or Like List Range TBL$ Partition extended names
Given a join operation between two tables, the optimizer recognizes when partition-wise join (full or partial) is applicable, decides whether to use it or not and annotate the join properly when it decides to use it. This applies to both serial and parallel cases.
To recognize full partition-wise join the optimizer relies on the definition of equi-partitioning of two objects, this definition includes the equivalence of the virtual expression on which the tables were partitioned.
|
| Oracle 11g Reference Partitioning |
作者 tomszrp 19:08 |
静态链接网址 |
最新回复 (0) |
引用 (0) |
磨刀石 |
|
摘录部分我的笔记的中doc,和大家一起感受Oracle 11g在分区方面的增强--引用分区 引用分区,也有人叫外键分区。 引用分区的特点 ●外键表可根据主键表来分区 外键表不需要包含分区键值 ●外键分区可与主键分区保持一定的关系 ●主键与外键的连接会是分区感知的 ●能很好的进行数据生命周期管理(ILM) 引用分区的适用场景 假设系统中有这样2个表:sales和customers create table customers
(
cust_id number primary key,
cust_name varchar2(64),
rating varchar2(1) not null
)
partition by list(rating)
(
partition p_1 values('A'),
partition p_2 values('B')
);
create table sales
(
sales_id number primary key,
cust_id number not null,
sales_amt number,
constraint fk_sales
foreign key(cust_id)
references customers
);
一般情况下,我们都会期望采用相同的方式对sales和customers表分区,比如都通过rating列进行list分区。但现在的情况是:sales表中没有名为
rating这样的列(减少冗余),那么就提出这样一个问题,能否根据这个不存在的列进行分区呢?这个问题,在Oracle 11g之前,是没有办法来解决的,我们只能采用其他的方式来规避实现我们的目标,在11g中,我们可以使用Reference分区的特性,下面的示例就是针对上面的问题的一个解决方法(11g) Connected to Oracle Database 11g Enterprise Edition Release 11.1.0.6.0
Connected as study
SQL> create table customers
2 (
3 cust_id number primary key,
4 cust_name varchar2(64),
5 rating varchar2(1) not null
6 )
7 partition by list(rating)
8 (
9 partition p_1 values('A'),
10 partition p_2 values('B')
11 );
Table created
SQL> create table sales
2 (
3 sales_id number primary key,
4 cust_id number not null,
5 sales_amt number,
6 constraint fk_sales
7 foreign key(cust_id)
8 references customers
9 )
10 partition by reference(fk_sales);
Table created
SQL>
SQL> select table_name,partitioning_type,partition_count
2 from user_part_tables
3 where table_name='CUSTOMERS';
TABLE_NAME PARTITIONING_TYPE PARTITION_COUNT
----------------- ----------------- ---------------
CUSTOMERS LIST 2
SQL> select table_name,partition_name,high_value
2 from user_tab_partitions
3 where table_name='CUSTOMERS';
TABLE_NAME PARTITION_NAME HIGH_VALUE
--------------- ------------------- -----------------
CUSTOMERS P_1 'A'
CUSTOMERS P_2 'B'
SQL> select table_name,partitioning_type,partition_count,ref_ptn_constraint_name
2 from user_part_tables
3 where table_name='SALES';
TABLE_NAME PARTITIONING_TYPE PARTITION_COUNT REF_PTN_CONSTRAINT_NAME
------------- ----------------- --------------- ---------------------------
SALES REFERENCE 2 FK_SALES
SQL> select table_name,partition_name
2 from user_tab_partitions
3 where table_name='SALES';
TABLE_NAME PARTITION_NAME
--------------- ------------------
SALES P_1
SALES P_2
SQL> insert into customers values(1001,'Oracle','A');
1 row inserted
SQL> insert into customers values(1002,'IBM','B');
1 row inserted
SQL> commit;
Commit complete
SQL> insert into sales values(101,1001,1);
1 row inserted
SQL> insert into sales values(102,1001,2);
1 row inserted
SQL> insert into sales values(103,1002,1);
1 row inserted
SQL> commit;
Commit complete
SQL> select * from sales partition (p_1);
SALES_ID CUST_ID SALES_AMT
---------- ---------- ----------
101 1001 1
102 1001 2
SQL> select * from sales partition (p_2);
SALES_ID CUST_ID SALES_AMT
---------- ---------- ----------
103 1002 1
SQL>
|
| Oracle 11g More Composite Partitioning |
作者 tomszrp 23:14 |
静态链接网址 |
最新回复 (0) |
引用 (0) |
磨刀石 |
|
摘录部分我的笔记的中doc,和大家一起感受Oracle 11g在分区方面的增强--扩展的组合分区 从前面的分区方法的一节的表格中可以看到,从8i开始,Oracle就引入了组合分区--可以在分区中创建子分区,从而进一步将表细分。 随着Oracle的版本的发展,组合分区的方式也在不停的增强。到了11g,提供了多大9种的组合类型。 这部分内容相对容易理解,本案例中不再做过多的介绍,下面仅给出一个我们以前(11g前)未曾接触过的list-list组合分区的例子: Connected to Oracle Database 11g Enterprise Edition Release 11.1.0.6.0
Connected as study
SQL> create table list_list_test
2 (
3 region number(4),
4 status varchar2(4),
5 statusdate date
6 )
7 partition by list(region)
8 subpartition by list(status)
9 (
10 partition p_531 values(531)
11 (
12 subpartition p_531_a values('A'),
13 subpartition p_531_b values('B'),
14 subpartition p_531_c values('C'),
15 subpartition p_531_def values(default)
16 ),
17 partition p_532 values(532)
18 (
19 subpartition p_532_a values('A'),
20 subpartition p_532_b values('B'),
21 subpartition p_532_c values('C'),
22 subpartition p_532_def values(default)
23 )
24 );
Table created
SQL> select table_name,partitioning_type,subpartitioning_type
2 from user_part_tables
3 where table_name='LIST_LIST_TEST';
TABLE_NAME PARTITIONING_TYPE SUBPARTITIONING_TYPE
-------------------- ----------------- --------------------
LIST_LIST_TEST LIST LIST
SQL> select table_name,partition_name,subpartition_name,subpartition_position,tablespace_name
2 from user_tab_subpartitions
3 where table_name='LIST_LIST_TEST'
4 order by partition_name,subpartition_position;
TABLE_NAME PARTITION_NAME SUBPARTITION_NAME SUBPARTITION_POSITION TABLESPACE_NAME
----------------- --------------- -------------------- --------------------- ----------------
LIST_LIST_TEST P_531 P_531_A 1 STUDY
LIST_LIST_TEST P_531 P_531_B 2 STUDY
LIST_LIST_TEST P_531 P_531_C 3 STUDY
LIST_LIST_TEST P_531 P_531_DEF 4 STUDY
LIST_LIST_TEST P_532 P_532_A 1 STUDY
LIST_LIST_TEST P_532 P_532_B 2 STUDY
LIST_LIST_TEST P_532 P_532_C 3 STUDY
LIST_LIST_TEST P_532 P_532_DEF 4 STUDY
8 rows selected
SQL>
这部分内容相对比较容易理解,我在doc中也没有做过多的介绍。
|
| Oracle 11g System Partitioning |
作者 tomszrp 22:10 |
静态链接网址 |
最新回复 (0) |
引用 (0) |
磨刀石 |
|
摘录部分我的笔记的中doc,和大家一起感受Oracle 11g在分区方面的增强--System Partitioning 系统分区的特点 ●系统分区与其他分区相比,一个最根本的区别就是不需要指定分区KEY值 ●数据会进入哪个分区由应用程序决定,实际上也就是由SQL来决定,在Insert语句中可以指定插入哪个分区 ●因为System Partitioning分区表没有分区字段,所以一般分区表的performance benefits对System Partitioning分区表不再适用(包括分区表智能裁剪和智能联接) ●对于按“系统”方法进行分区的表, 必须对 DML 使用分区扩展名或绑定变量 ●记录放在哪个分区与记录没有任何关系,同样的记录可以存放到不同的分区中 ●The following operations are supported for system partitioned tables: Partition maintenance operations and other DDLs (See exceptions below) Creation of local indexes. Creation of local bitmapped indexes. Creation of global indexes. All DML operations. ●insert 操作支持三种写法 INSERT with partition extended syntax: insert into <base_table> partition (<partition_name|dataobj_to_partition(table_name,:data_object_id)>) 其中data_object_id通过dba_objects视图中获取 参考文档:<Oracle Database Data Cartridge Developer's Guide> 11g Realses 1(11.1) Part Number B28425-01
●Because of the peculiar requirements of system partitioning, the following operations are not supported for system partitioning: Unique local indexes are not supported because they require a partitioning key. CREATE TABLE AS SELECT(不能通过CTAS创建System Partitioning表) Since there is no partitioning method, it is not possible to distribute rows to partitions. Instead the user should first create the table and then insert rows into each partition. INSERT INTO <tabname> AS <subquery> SPLIT PARTITION operations 说明 或许我们对Oracle提供的这个新特性的实际用途使用很少,但不难看出这确实是一个非常人性化的变革,所以我们也不得不认真、仔细的认识并研究他。或许将来我们有一个这样的需求: 假设有一个无法使用任何逻辑方法进行分区的表,结果将是一个巨大的、单一的表。不难想象这将导致需要扩展的索引维护和其他操作问题的出现。于是,开发那边可以提出一个这样的要求:他们可以通过某种智能算法写入分区,通过应用来控制特定的记录写入到某个分区,而对DBA来说,就只需要定义一个system partitiion table即可。 示例一:System Partitioning初体验 Connected to Oracle Database 11g Enterprise Edition Release 11.1.0.6.0
Connected as study
SQL> create table sys_part_test
2 (
3 region number(4),
4 recdate date
5 )
6 partition by system
7 (
8 partition p1,
9 partition p2,
10 partition p3,
11 partition p4
12 );
Table created
SQL> insert into sys_part_test partition (p1) values(531,sysdate);
1 row inserted
SQL> insert into sys_part_test partition (p2) values(532,sysdate);
1 row inserted
SQL> insert into sys_part_test partition (p3) values(533,sysdate);
1 row inserted
SQL> insert into sys_part_test partition (p4) values(534,sysdate);
1 row inserted
SQL> commit;
Commit complete
SQL> select * from sys_part_test;
REGION RECDATE
------ -----------
531 2007-12-14
532 2007-12-14
533 2007-12-14
534 2007-12-14
SQL> insert into sys_part_test partition (p1) select * from sys_part_test partition (p4);
1 row inserted
SQL> commit;
Commit complete
SQL> select * from sys_part_test partition (p1);
REGION RECDATE
------ -----------
531 2007-12-14
534 2007-12-14
SQL> select * from sys_part_test partition (p2);
REGION RECDATE
------ -----------
532 2007-12-14
SQL> select * from sys_part_test partition (p3);
REGION RECDATE
------ -----------
533 2007-12-14
SQL> select * from sys_part_test partition (p4);
REGION RECDATE
------ -----------
534 2007-12-14
SQL> select *from sys_part_test;
REGION RECDATE
---------- -------------------
531 2007-12-14 17:21:13
534 2007-12-14 17:21:32
532 2007-12-14 17:21:20
533 2007-12-14 17:21:26
534 2007-12-14 17:21:32
SQL> update sys_part_test set recdate=sysdate where region=533;
已更新 1 行。
SQL> select *from sys_part_test;
REGION RECDATE
---------- -------------------
531 2007-12-14 17:21:13
534 2007-12-14 17:21:32
532 2007-12-14 17:21:20
533 2007-12-14 17:27:19
534 2007-12-14 17:21:32
SQL> delete from sys_part_test partition(p4);
已删除 1 行。
SQL> select *from sys_part_test;
REGION RECDATE
---------- -------------------
531 2007-12-14 17:21:13
534 2007-12-14 17:21:32
532 2007-12-14 17:21:20
533 2007-12-14 17:27:19
SQL>
示例二:System Partitioning Insert三种方法体验 D:>sqlplus study/study@ora11g
SQL*Plus: Release 11.1.0.6.0 - Production on 星期六 12月 15 10:41:13 2007
Copyright (c) 1982, 2007, Oracle. All rights reserved.
连接到:
Oracle Database 11g Enterprise Edition Release 11.1.0.6.0 - Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
SQL> create table sys_part_test
2 (
3 region number(4),
4 recdate date
5 )
6 partition by system
7 (
8 partition p1,
9 partition p2,
10 partition p3,
11 partition p4
12 );
表已创建。
SQL> insert into sys_part_test partition (p1) values (531,sysdate); --方法一,指定partition_name
已创建 1 行。
SQL> commit;
提交完成。
SQL> select * from sys_part_test;
REGION RECDATE
---------- -------------------
531 2007-12-15 10:41:43
SQL> select object_name,subobject_name,object_id,data_object_id,object_type
2 from user_objects
3 where object_name='SYS_PART_TEST';
OBJECT_NAME SUBOBJECT_NAME OBJECT_ID DATA_OBJECT_ID OBJECT_TYPE
-------------- ----------------- ----------- -------------- ---------------
SYS_PART_TEST 69632 TABLE
SYS_PART_TEST P1 69633 69633 TABLE PARTITION
SYS_PART_TEST P2 69634 69634 TABLE PARTITION
SYS_PART_TEST P3 69635 69635 TABLE PARTITION
SYS_PART_TEST P4 69636 69636 TABLE PARTITION
SQL> insert into sys_part_test partition(dataobj_to_partition(sys_part_test,69634)) values (532,sysdate);
已创建 1 行。 --方法二,通过data object id
SQL> commit;
提交完成。
SQL> select *from sys_part_test;
REGION RECDATE
---------- -------------------
531 2007-12-15 10:41:43
532 2007-12-15 10:43:44
SQL> select *from sys_part_test partition (p2);
REGION RECDATE
---------- -------------------
532 2007-12-15 10:43:44
SQL> var p_obj number;
SQL> exec :p_obj:=69635
PL/SQL 过程已成功完成。 --如下为方法三,通过data object id但使用bind var
SQL> insert into sys_part_test partition(dataobj_to_partition(sys_part_test,:p_obj)) values (533,sysdate);
已创建 1 行。
SQL> insert into sys_part_test partition(dataobj_to_partition(sys_part_test,:p_obj)) values (533,sysdate);
已创建 1 行。
SQL> commit;
提交完成。
SQL> select * from sys_part_test;
REGION RECDATE
---------- -------------------
531 2007-12-15 10:41:43
532 2007-12-15 10:43:44
533 2007-12-15 10:45:19
533 2007-12-15 10:45:21
SQL> select * from sys_part_test partition (p3);
REGION RECDATE
---------- -------------------
533 2007-12-15 10:45:19
533 2007-12-15 10:45:21
SQL> select * from sys_part_test partition (p2);
REGION RECDATE
---------- -------------------
532 2007-12-15 10:43:44
SQL> select * from sys_part_test partition (p1);
REGION RECDATE
---------- -------------------
531 2007-12-15 10:41:43
SQL>
...
|
| oracle 11g Interval Partitioning |
作者 tomszrp 20:05 |
静态链接网址 |
最新回复 (1) |
引用 (0) |
磨刀石 |
|
摘录部分我的笔记的中doc,和大家一起感受Oracle 11g在分区方面的增强 Oracle 11g中Interval Partitioning分区实际上是由range分区引申而来,最终实现了range分区的自动化。 间隔分区的特点 ●由range分区派生而来 ●以定长宽度创建分区(比如年、月、具体的数字(比如100、500等)) ●分区字段必须是number或date类型 ●必须至少指定一个range分区(永久分区) ●当有记录插入时,系统根据需要自动创建新的分区和本地索引 ●已有的范围分区可被转换成间隔分区(通过ALTER TABLE SET INTERVAL选项完成) ●Interval Partitioning不支持支持索引组织表 ●在Interval Partitioning表上不能创建domain index (补充说明:域索引 域索引是程序专用(TEXT,SPATIAL)索引,作为一个索引类型通过例程管理和访问,之所以叫做域索引是因为它的索引数据在程序专用区域。 只有单行索引被域索引支持 可以创建单行域索引在纯量,对象,或者LOB数据类型字段上 全文索引、空间索引就是域索引的一种。 简单的说,是Oracle支持的一种可以有用户自己定制规则的索引.其中全文索引和空间索引等是Oracle已经定义好的域索引 ) 说明 1)对于采用date类型的Interval Partitioning可以支持按year、month、day、hour、minute、second六种类型的定长宽度分区,分别通过如下函数转换 numtoyminterval ( n, { 'YEAR'|'MONTH'}) numtodsinterval ( n, { 'DAY'|'HOUR'|'MINUTE'|'SECOND'}) 具体的用法可以参见下面的例子。 2)对于采用number类型的Interval Partitioning必须按照固定的宽度分区 下面用几个具体的例子来感受一下Interval Partitioning 示例一:DATE类型按YEAR Interval Partitioning Connected to Oracle Database 11g Enterprise Edition Release 11.1.0.6.0
Connected as study
SQL> create table interval_test_by_year
2 ( region number(4),
3 recdate date not null,
4 recoid number
5 )
6 partition by range(recdate)
7 interval(numtoyminterval(1,'year'))
8 (
9 partition p1 values less than(to_date('20050101','yyyymmdd'))
10 );
Table created
SQL> select table_name,partition_name,high_value
2 from user_tab_partitions
3 where table_name='INTERVAL_TEST_BY_YEAR'
4 order by partition_position;
TABLE_NAME PARTITION_NAME HIGH_VALUE
---------------------- --------------- --------------------------------------------------------------------------------
INTERVAL_TEST_BY_YEAR P1 TO_DATE(' 2005-01-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA
SQL> select table_name,partitioning_type,status,interval from user_part_tables
2 where table_name='INTERVAL_TEST_BY_YEAR';
TABLE_NAME PARTITIONING_TYPE STATUS INTERVAL
----------------------- ----------------- -------- --------------------------
INTERVAL_TEST_BY_YEAR RANGE VALID NUMTOYMINTERVAL(1,'YEAR')
SQL> select * from interval_test_by_year;
REGION RECDATE RECOID
------ ----------- ----------
SQL> insert into interval_test_by_year values(531,to_date('20040101','yyyymmdd'),1);
1 row inserted
SQL> insert into interval_test_by_year values(531,to_date('20050101','yyyymmdd'),2);
1 row inserted
SQL> insert into interval_test_by_year values(531,to_date('20060101','yyyymmdd'),3);
1 row inserted
SQL> commit;
Commit complete
SQL> select table_name,partition_name,high_value
2 from user_tab_partitions
3 where table_name='INTERVAL_TEST_BY_YEAR'
4 order by partition_position;
TABLE_NAME PARTITION_NAME HIGH_VALUE
---------------------- ---------------- --------------------------------------------------------------------------------
INTERVAL_TEST_BY_YEAR P1 TO_DATE(' 2005-01-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA
INTERVAL_TEST_BY_YEAR SYS_P61 TO_DATE(' 2006-01-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA
INTERVAL_TEST_BY_YEAR SYS_P62 TO_DATE(' 2007-01-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA
SQL> select * from interval_test_by_year;
REGION RECDATE RECOID
------ ----------- ----------
531 2004-1-1 1
531 2005-1-1 2
531 2006-1-1 3
SQL> select * from interval_test_by_year partition (p1);
REGION RECDATE RECOID
------ ----------- ----------
531 2004-1-1 1
SQL> select * from interval_test_by_year partition (sys_p61);
REGION RECDATE RECOID
------ ----------- ----------
531 2005-1-1 2
SQL> select * from interval_test_by_year partition (sys_p62);
REGION RECDATE RECOID
------ ----------- ----------
531 2006-1-1 3
SQL>
示例二:DATE类型按monh Interval Partitioning Connected to Oracle Database 11g Enterprise Edition Release 11.1.0.6.0
Connected as study
SQL> create table interval_test_by_month
2 ( region number(4),
3 recdate date not null,
4 recoid number
5 )
6 partition by range(recdate)
7 interval(numtoyminterval(1,'month'))
8 (
9 partition p1 values less than(to_date('20071201','yyyymmdd'))
10 );
Table created
SQL> select table_name,partition_name,high_value
2 from user_tab_partitions
3 where table_name='INTERVAL_TEST_BY_MONTH'
4 order by partition_position;
TABLE_NAME PARTITION_NAME HIGH_VALUE
----------------------- ---------------- --------------------------------------------------------------------------------
INTERVAL_TEST_BY_MONTH P1 TO_DATE(' 2007-12-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA
SQL> select table_name,partitioning_type,status,interval from user_part_tables
2 where table_name='INTERVAL_TEST_BY_MONTH';
TABLE_NAME PARTITIONING_TYPE STATUS INTERVAL
----------------------- ----------------- -------- --------------------------
INTERVAL_TEST_BY_MONTH RANGE VALID NUMTOYMINTERVAL(1,'MONTH')
SQL> insert into interval_test_by_month values(531,to_date('20071212','yyyymmdd'),1);
1 row inserted
SQL> insert into interval_test_by_month values(531,to_date('20080110','yyyymmdd'),2);
1 row inserted
SQL> insert into interval_test_by_month values(531,to_date('20090101','yyyymmdd'),3);
1 row inserted
SQL> commit;
Commit complete
SQL> select table_name,partition_name,high_value
2 from user_tab_partitions
3 where table_name='INTERVAL_TEST_BY_MONTH'
4 order by partition_position;
TABLE_NAME PARTITION_NAME HIGH_VALUE
------------------------ ---------------- --------------------------------------------------------------------------------
INTERVAL_TEST_BY_MONTH P1 TO_DATE(' 2007-12-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA
INTERVAL_TEST_BY_MONTH SYS_P63 TO_DATE(' 2008-01-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA
INTERVAL_TEST_BY_MONTH SYS_P64 TO_DATE(' 2008-02-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA
INTERVAL_TEST_BY_MONTH SYS_P65 TO_DATE(' 2009-02-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA
SQL> select * from interval_test_by_month partition (p1);
REGION RECDATE RECOID
------ ----------- ----------
SQL> select * from interval_test_by_month partition (sys_p63);
REGION RECDATE RECOID
------ ----------- ----------
531 2007-12-12 1
SQL> select * from interval_test_by_month partition (sys_p64);
REGION RECDATE RECOID
------ ----------- ----------
531 2008-1-10 2
SQL> select * from interval_test_by_month partition (sys_p65);
REGION RECDATE RECOID
------ ----------- ----------
531 2009-1-1 3
SQL>
示例三:DATE类型按day Interval Partitioning Connected to Oracle Database 11g Enterprise Edition Release 11.1.0.6.0
Connected as study
SQL> create table interval_test_by_day
2 ( region number(4),
3 recdate date not null,
4 recoid number
5 )
6 partition by range(recdate)
7 interval(numtodsinterval(1,'day'))
8 (
9 partition p1 values less than(to_date('20071201','yyyymmdd'))
10 );
Table created
SQL> select table_name,partition_name,high_value
2 from user_tab_partitions
3 where table_name='INTERVAL_TEST_BY_DAY'
4 order by partition_position;
TABLE_NAME PARTITION_NAME HIGH_VALUE
---------------------- ---------------- --------------------------------------------------------------------------------
INTERVAL_TEST_BY_DAY P1 TO_DATE(' 2007-12-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA
SQL> select table_name,partitioning_type,status,interval from user_part_tables
2 where table_name='INTERVAL_TEST_BY_DAY';
TABLE_NAME PARTITIONING_TYPE STATUS INTERVAL
---------------------- ----------------- -------- ------------------------
INTERVAL_TEST_BY_DAY RANGE VALID NUMTODSINTERVAL(1,'DAY')
SQL> insert into interval_test_by_day values(531,to_date('20071202','yyyymmdd'),1);
1 row inserted
SQL> insert into interval_test_by_day values(531,to_date('20071203','yyyymmdd'),2);
1 row inserted
SQL> insert into interval_test_by_day values(531,to_date('20081205','yyyymmdd'),3);
1 row inserted
SQL> commit;
Commit complete
SQL> select table_name,partition_name,high_value
2 from user_tab_partitions
3 where table_name='INTERVAL_TEST_BY_DAY'
4 order by partition_position;
TABLE_NAME PARTITION_NAME HIGH_VALUE
---------------------- ---------------- --------------------------------------------------------------------------------
INTERVAL_TEST_BY_DAY P1 TO_DATE(' 2007-12-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA
INTERVAL_TEST_BY_DAY SYS_P66 TO_DATE(' 2007-12-03 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA
INTERVAL_TEST_BY_DAY SYS_P67 TO_DATE(' 2007-12-04 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA
INTERVAL_TEST_BY_DAY SYS_P68 TO_DATE(' 2008-12-06 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA
SQL> select table_name,partitioning_type,status,interval from user_part_tables
2 where table_name='INTERVAL_TEST_BY_DAY';
TABLE_NAME PARTITIONING_TYPE STATUS INTERVAL
---------------------- ----------------- -------- ------------------------
INTERVAL_TEST_BY_DAY RANGE VALID NUMTODSINTERVAL(1,'DAY')
SQL> insert into interval_test_by_day values(531,to_date('20081204','yyyymmdd'),4);
1 row inserted
SQL> commit;
Commit complete
SQL> select table_name,partition_name,high_value
2 from user_tab_partitions
3 where table_name='INTERVAL_TEST_BY_DAY'
4 order by partition_position;
TABLE_NAME PARTITION_NAME HIGH_VALUE
---------------------- ---------------- --------------------------------------------------------------------------------
INTERVAL_TEST_BY_DAY P1 TO_DATE(' 2007-12-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA
INTERVAL_TEST_BY_DAY SYS_P66 TO_DATE(' 2007-12-03 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA
INTERVAL_TEST_BY_DAY SYS_P67 TO_DATE(' 2007-12-04 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA
INTERVAL_TEST_BY_DAY SYS_P69 TO_DATE(' 2008-12-05 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA
INTERVAL_TEST_BY_DAY SYS_P68 TO_DATE(' 2008-12-06 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA
SQL>
说明:按照hour,minute,second的和上面的做法类似,本案例不再示例中不再介绍. 示例四:NUMBER类型按定长间隔分区 假设我们的系统中有一张存放员工薪水的表,由于公司员工很多,为了便于管理,我们按照员工的薪水将这张表分区,每2000一个档次,以前的做法是: create table interval_test_by_number
( empno number(6),
name varchar2(20),
sal number(6)
)
partition by range(salary)
(
partition p_2k values less than (2001),
partition p_4k values less than (4001),
partition p_6k values less than (6001),
partition p_8k values less than (8001)
partition p_10k values less than (10001)
partition p_max values less than (maxvalue)
); 设置5个档次,分别从2K到10K,预留一个maxvalue分区,考虑将来随着物价的上涨,员工的薪水可能会超过10K,到时候通过split动作来新扩展 分区.
那么到了11g中,我们就不需要这么麻烦了,完全可以提交给Oracle,利用Interval Partitioning技术,让系统自动完成。对DBA来说,只需要创建一个基本salary薪水的分区即可。以后谁着公司的薪酬体系的变化,系统会自动扩展需要的分区。比如: Connected to Oracle Database 11g Enterprise Edition Release 11.1.0.6.0
Connected as study
SQL> create table interval_test_by_number
2 (empno number(6),
3 name varchar2(20),
4 sal number(6)
5 )
6 partition by range(sal)
7 Interval (2000)
8 (
9 partition p_2k values less than (2001)
10 );
Table created
SQL> select table_name,partition_name,high_value
2 from user_tab_partitions
3 where table_name='INTERVAL_TEST_BY_NUMBER'
4 order by partition_position;
TABLE_NAME PARTITION_NAME HIGH_VALUE
-------------------------- ----------------- ------------
INTERVAL_TEST_BY_NUMBER P_2K 2001
SQL> select table_name,partitioning_type,status,interval from user_part_tables
2 where table_name='INTERVAL_TEST_BY_NUMBER';
TABLE_NAME PARTITIONING_TYPE STATUS INTERVAL
------------------------- ----------------- -------- ---------
INTERVAL_TEST_BY_NUMBER RANGE VALID 2000
SQL> insert into interval_test_by_number values (1001,'thomas zhang',1800);
1 row inserted
SQL> insert into interval_test_by_number values (1002,'zhangrunping',2500);
1 row inserted
SQL> insert into interval_test_by_number values (1003,'zrp',3000);
1 row inserted
SQL> insert into interval_test_by_number values (1005,'CEO',9999);
1 row inserted
SQL> commit;
Commit complete
SQL> select table_name,partition_name,high_value
2 from user_tab_partitions
3 where table_name='INTERVAL_TEST_BY_NUMBER'
4 order by partition_position;
TABLE_NAME PARTITION_NAME HIGH_VALUE
------------------------- ----------------- ------------
INTERVAL_TEST_BY_NUMBER P_2K 2001
INTERVAL_TEST_BY_NUMBER SYS_P73 4001
INTERVAL_TEST_BY_NUMBER SYS_P74 10001
SQL>
|
| ORA-00001: 违反唯一约束条件 (SYS.I_INDPART_BOPART$) BUG(3748430) |
作者 tomszrp 21:53 |
静态链接网址 |
最新回复 (0) |
引用 (0) |
磨刀石 |
|
这几天在做Oracle分区技术的培训稿,为了保证培训效果,在9i,10g,11g上分别对各种分区技术和管理方法进行了详细的测试,没想到就踩到了这个雷.下面是详细的过程,希望对后学者有所帮助. 下面是这个bug的再现过程:
Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.3.0
Connected as study
SQL> create table part_demo
2 (
3 region number(4),
4 recdate date,
5 servnumber varchar2(11)
6 ) tablespace users;
Table created
SQL> create index g_range_part_demo on part_demo(region,servnumber)
2 global
3 partition by hash (region)
4 partitions 4;
Index created
SQL> select index_name,partition_name,status,tablespace_name,partition_position
2 from user_ind_partitions
3 where index_name=upper('g_range_part_demo')
4 order by partition_position;
INDEX_NAME PARTITION_NAME STATUS TABLESPACE_NAME PARTITION_POSITION
------------------- ---------------- -------- ---------------- ------------------
G_RANGE_PART_DEMO SYS_P125 USABLE STUDY 1
G_RANGE_PART_DEMO SYS_P126 USABLE STUDY 2
G_RANGE_PART_DEMO SYS_P127 USABLE STUDY 3
G_RANGE_PART_DEMO SYS_P128 USABLE STUDY 4
SQL>
SQL> select obj#,dataobj#,bo#,part#,flags
2 from SYS.INDPART$
3 where obj# in (select object_id from dba_objects where object_name='G_RANGE_PART_DEMO');
OBJ# DATAOBJ# BO# PART# FLAGS
---------- ---------- ---------- ---------- ----------
52650 52650 52649 1 0
52652 52652 526 | |