1Privilgeges
1) Database security:
--System security
--Data security
2)System privileges:Caining access to the database
3)Object privileges:manipulationg thee content of the database objects
4)Schemas:Collections of objects ,such as tables,views,and sequences
2System Privileges
. More than 100 privileges are available;
. The database administrator has high-levle system privileges for tasks such as:
creating new user,removing user,removing tables,backing up tables
3 Creating user
the dba creates users by using the create user statement
create user user
identified by password;
e.g create user object scott
identified by tiger;
SQL> create user testuser
2 identified by test;
User created
SQL> conn testuser/test@orcl2000
Not logged on
SQL> grant access session to testuser;
grant access session to testuser
Not logged on
SQL> conn digit_cc/digit_cc@orcl2000
Connected to Oracle9i Enterprise Edition Release 9.2.0.1.0
Connected as digit_cc
SQL> grant create session to testuser;
Grant succeeded
SQL> conn testuser/test@orcl2000;
Connected to Oracle9i Enterprise Edition Release 9.2.0.1.0
Connected as testuser
4 user System privileges
once a user is created,the dba can grant specific system privileges to a user
grant privilege[,privilege...]
to user [,user|role,public...];
DBA can grant a user specific system privileges
grant create session,create table,create sequence,create view to scott;
5 creating and granting privileges to role
' Create a role
create role manager;
.grant privileges to a role
grant create table,create view to manager
.Grant a role to user
grant manager to kochar;
SQL> create role testrole;
Role created
SQL> grant create table,create view,create sequence to testrole;
Grant succeeded
SQL> grant testrole to testuser;
6 change your password
you can change your password by using the alter user statement;
alter user scott
indetified by lion;
7 object privileges
object privileges vary from object to object
an owner has all the privilege to the object
an owner can give specific privilege on that owner object
grant select on auther to testuser;
grant select on outher to testuser with grant option -- testuser also can grant it to
other user;
grant update(department_name,location_id)
on departments
to scott,manager;
8 how to revoke object privileges
--you use the revoke statement to revoke privileges granted to other users
--privileges granted to other users through the with grant option clause are also revoked.
revoke privilege {[,privilege...]|all} on object
from {user[,user....]|role|public}
[cascade constraints]
revoke select on author from user;
9 Database Links
Database link allow user to access data in the remote database;
SQL> create database link kjw1
2 connect to digit_cc identified by digit_cc
3 using 'orcl2000';
Database link created
SQL> select * from digit_cc.table_action@kjw1;
链接到远程数据库
在一个分布式的环境里,数据库链接是定义到其它数据库的路径的一个重要方法,使得远程处理天衣无缝。
要获得数据库链接的更深奥的知识,查看Oracle8i SQL Reference(Oracle8i SQL参考)和Oracle8i Concepts (Oracle8i概念手册)。详细资料的另一个极好的来源是Oracle8i Distributed Database Systems(Oracle8i分布式数据库系统手册)。
今天许多运行Oracle的机构有不止一个Oracle数据库。有时不管原计划是否这样,一个数据库中的数据可能与另一数据库中的数据关联。出现这种情况时,你可以链接这两个数据库使得用户或应用程序可以访问所有数据,就好象它们在一个数据库中。当你这么做时,你就有了一个分布式数据库系统。
如何将两个数据库链接在一起呢?使用一个数据库链接来完成。数据库链接是定义一个数据库到另一个数据库的路径的对象。数据库链接允许你查询远程表及执行远程程序。在任何分布式环境里,数据库链接都是必要的。
简单案例
数据库链接的目的是定义一条到远程数据库的路径,使你可以通过在本地执行一条SQL语句来使用那个数据库中的表和其它的对象。例如,你在一个远程数据库上有一个称之为"geographic feature name"的表,而你想在已连接到你本地数据库的情况下访问那些数据。数据库链接正是你所需要的。在建立它之前,你必须搜集如下信息:
一个网络服务名称,你的本地数据库事例能够使用它来与远程事例相连接远程数据库上的有效用户名和口令网络服务名称是每一个数据库链接必需的。每一次你从客户机PC使用SQL*Plus连接到你的数据库时都要使用服务名称。在那些情况下,你提供给SQL*Plus的网络服务名称是通过在你的客户机上的nsnames.ora文件中查找它们来解析的。在数据库链接中使用的网络服务名称也是如此,除非是那些名字是使用驻留在服务器上的tnsnames.ora文件来解析。
在你定义数据库链接时指定的用户名和口令,用于建立与远程事例的连接。不需硬编码用户名和口令,建立数据库链接也是可能的甚至是值得选取的。既然这样,现在我们注意这个最直接的例子。
下列语句建立了一个数据库链接,它允许访问客户帐户,这个帐户是事先在GNIS数据库建好的:
CREATE DATABASE LINK GNIS
CONNECT TO GUEST IDENTIFIED BY WELCOME
USING 'GNIS';
链接名称GNIS紧随LINK关键字。当连接到远程事例时,CONNECT TO...IDENTIFIED子句指定UEST/WELCOME作为用户名和口令使用 。USING子句指定通过网络服务名称GNIS建立连接。使用这一链接,现在你可以在远程数据库上查询数据。例如:
SQL> SELECT GFN_FEATURE_NAME
2 FROM GNIS.FEATURE_NAMES@GNIS
3 WHERE GFN_FEATURE_TYPE='falls'
4 AND GFN_STATE_ABBR='MI'
5 AND GFN_COUNTY_NAME='Alger';
GFN_FEATURE_NAME
_________________
Alger Falls
Au Train Falls
Chapel Falls
Miners Falls
Mosquito Falls
Tannery Falls
..
在SELECT语句中@GNIS紧随表名称,说明GNIS.FEATURE_NAMES表是在远程数据库,应该通过GNIS链接访问,链接类型Oracle支持几种不同类型的链接。这些类型相互重叠,有时难以通过选项进行分类。当你建立数据库链接时,你需要从下面选取:
Public(公用)或Private (私有)链接
权限类: Fixed User(固定用户), Connected User(连接用户)或 Current User(当前用户)
Shared Link(共享链接)或 Not Shared Link(非共享链接)
每次创建数据库链接时,你要自觉不自觉地做这三种选择。
公用链接与私有链接相对比
公用数据库链接对所有的数据库用户开放访问权。前面显示的是私有数据库链接,它只对建立它的用户授权。公用数据库链接更为有用,因为它使你不必为每一个潜在用户创建单独的链接。为了建立一个公用数据库链接,使用如下显示的PUBLIC关键字:
CREATE PUBLIC DATABASE LINK GNIS
CONNECT TO GUEST IDENTIFIED BY WELCOME
USING 'GNIS';
即使这是一个公用链接,用户名仍旧固定。所有使用这个链接的用户都作为用户GUEST连接到远程数据库。
使用数据库链接访问远程表
图1 数据库链接GNIS,指明网络服务名称,链接PROD事例到GNIS事例中的FEATURE_NAMES表。
权限类
当你建立一个数据库链接时,关于你如何授权对远程数据库进行访问,有三种选择。这三种选择代表了数据库链接的另一种分类方法。这三种类别如下:
固定用户。为远程数据库链接指定用户名和口令,作为数据库链接定义的一部分。
连接用户。在不指定用户名和口令时创建的数据库链接。
当前用户。建立数据库链接并指定CURRENT_USER关键字。
固定用户数据库链接是指在创建链接时为远程数据库指定用户名和口令。这一链接不管什么时候使用,也无论谁使用,都使用相同的用户名和口令登陆到远程数据库。到目前为止你在本文中所看到的都是固定用户链接。
固定用户链接,尤其是公用固定用户链接的一个潜在问提是他们把远程系统上的同一帐户给了许多本地用户。从安全角度来说,如果所有的本地用户在远程系统上拥有同一个帐户,责任就要折中,这取决于用户的数量 。如果数据丢失,几乎不可能确定破坏是如何发生的。另一个潜在问题是公用固定用户链接将对远程数据库的访问权给了所有的本地数据库用户。
如果你不想在数据库链接中嵌入用户名和口令,Oracle提供给你另一个非常有用的选择。你可以建立一个连接用户链接。连接用户链接是这样的链接,它通过任一个正在使用该链接的本地数据库的用户的用户名和口令登陆到远程数据库。你可以通过简单地空出用户名和口令来建立一个连接用户链接。考虑如下定义:
CREATE PUBLIC DATABASE LINK GNIS
USING 'GNIS';
链接名是GNIS。它连接到远程数据库连接时使用的网络服务名称是GNIS,但是没有指定用户名和口令。当你在查询中使用这个链接时,它将向远程数据库发送你当前的用户名和口令。例如,如果你使用AHMAD/SECRET 登陆到你的本地数据库,那么AHMAD/SECRET将是你登陆到远程数据库时使用的用户名和口令。
为了使用一个连接用户链接,你必须在远程数据库上有一个帐号,了解这一点是很重要的。不但这样,而且你在两个数据库上应使用同样的用户和口令。如果本地登陆使用AHMAD/SECRET,那么登陆到远程数据库时也必须使用同样的用户名和口令。使用连接用户链接时,如果你的口令不同,你就无权登陆。
公用连接用户数据库链接尤其有用,因为你可以建立一个可被所有用户访问的链接,并且所有用户被分别使用他或她自己的用户名和口令授权。你获得责任方面的利益,没有将远程数据库向你的本地数据库上的每一位用户开放。代价是你必须在两个数据库上建立用户帐户,并且你必需确信口令保持一致。
当前用户链接通过使用CURRENT_USER关键字建立并且与连接用户链接相似。只有当使用Oracle Advanced Security Option(Oracle高级安全选项)时,你才能使用当前用户链接,这个链接只对授权使用X.509认证的用户有用。
共享链接
共享数据库链接是指该链接的多个用户可以共享同一个底层网络连接。例如,在有四位用户的MTS(多线程服务器)环境下,每一个共享服务器进程都将与远程服务器有一个物理链接,这四位用户共享这两个链接。
表面上,共享链接乍一听起来像是一件好事。在某些环境下的确如此,但是,当你考虑使用共享链接时,应当意识到这有许多局限性和警告:
如果你使用一个专用的服务器连接来连接到你的本地数据库,链接只能在你从那些连接中创建的多重会话间共享。 在MTS环境里,每一个共享服务器进程潜在地打开一个链接。所有的会话被同一共享服务器进程提供并且分享被那个进程打开的任意共享链接。因为在MTS环境里的一个共享服务器进程能够服务于许多用户连接,共享链接的使用可能导致打开的链接远多于所必须的链接。用SHARED关键字建立共享数据库链接。还必须使用AUTHENTICATED BY 子句在远程系统上指定一有效的用户名和口令。如下命令建立一个共享的、公用的、连接用户数据库链接:
CREATE SHARED PUBLIC DATABASE LINK GNIS
AUTHENTICATED BY DUMMY_USER IDENTIFIED BY SECRET
USING 'GNIS';
要获得创建链接和管理分布式系统的更多资料,请查阅Oracle Technology Network (http://otn.oracle.com/)。
使用AUTHENTICATED BY子句稍微有些困扰,但是由于实现共享链接的方式安全性决定它是必须的。这个例子中的用户名和口令DUMMY_USER/SECRET必须在远程系统上有效。然而,远程系统上使用的帐户仍就是连接用户的帐户。如果我以JEFF/SECRET登陆到我的本地数据库并使用我刚建好的共享链接,将会发生以下一系列事件:
为了打开链接,Oracle使用DUMMY_USER/SECRET向远程数据库授权。 然后,Oracle试图使用HMAD/SECRET使我登陆到远程数据库。共享链接的主要目的是减少两个数据库服务器之间的底层网络连接数量。它们最适合于MTS环境,在那你拥有大量的通过这一链接访问远程数据库的用户。观念上,你想让用户数量超过共享服务器进程的数量。那么你可以通过为每一共享服务器进程打开一个链接而不是每位用户打开一个链接的方法,节省资源。
查找关于数据库链接的资料
你可以从几个数据字典视图中获得建立好的数据库链接的资料。DBA_DB_LINKS视图为每一定义的链接返回一行。OWNER 列和DB_LINK列分别显示了这一链接的所有者及名称。对公用数据库链接,OWNER列将包含'PUBLIC'。如果你建立固定用户链接,用户名应在DBA_DB_LINKS视图的USERNAME列里,但是口令只能从SYS.LINK$视图中看到。默认情况下,只有具有SELECT ANY TABLE系统权限的DBA能够访问SYS.LINK$视图查看口令。你应该保护访问那个视图的权限。ALL_DB_LINKS 视图和 USER_DB_LINKS视图与 DBA_DB_LINKS视图相类似-它们分别显示了你能够访问的所有链接及你所拥有的全部链接。最后,V$DBLINK动态性能视图向你显示出任意给定时间你-当前用户,打开的全部数据库链接。
全局性的数据库名称
在分布式环境里,Oracle建议你的数据库链接名应与它们连接到的数据库的全局性名称相匹配。因此如果你正在连接到名称为GNIS.GENNICK.ORG的数据库,你应当将你的数据库链接命名为GNIS.GENNICK.ORG
为确定数据库的全局性名称,以SYSTEM登陆并查询GLOBAL_NAME视图:
SQL> SELECT * FROM GLOBAL_NAME;
GLOBAL_NAME
_______________
GNIS.GENNICK.ORG
由于历史的原因,默认情况下,全局性名称与数据库链接名称的之间的链接不是强制性的。不过,你可以通过设置GLOBAL_NAMES的初始化参数为TRUE来改变这一行为。例如:
SQL> SHOW PARAMETER GLOBAL_NAMES
NAME TYPE VALUE
________________________________________________________
global_names boolean TRUE
用于产生这个范例的事例要求你使用的数据库链接名,必须与目标数据库的全局性数据库名称相匹配。注意与一些Oracle文档中说的相反,关键是你的本地事例的GLOBAL_NAMES设置。如果你的本地事例中GLOBAL_NAMES=FALSE,你就能够使用数据库链接,而不用管它们是否与远程数据库的全局性名称相匹配。总的来说,如果你设置GLOBAL_NAMES=TRUE,你应该在你的所有事例中一律这么做。
1 sequence
1) automatically generatess unique numbers
is a sharable object
is typically used to create a primary key value
replaces applicaition code
speeds up the efficiency of accessing sequence
create sequence sequence
[increment by n]
[start with n]
[{maxvalue n |nomaxvalue}]
[{minvalue n |nominvalue}]
[{cycle|nocycle}]
[{cache n |nocache}]
create sequence dept_deptin_seq
increment by 10
start with 120
maxvalue 9999
nocache
nocycle
2) Confirming Sequences
verify your sequence values in the user_sequences data dictionary table
select sequence_name,min_value,max_value,increment_by,last_number
from user_sequences;
the last_number display the next available sequence number if nocache is specified
3)nextval and currval Pseudocolumns
--nextval return thee next available sequence value,it return a unique value every time
it si referenced,even for different ueer;
--currval obtains the current sequence value;
--nextval must be issued for that sequence before curval contains a value;
4) Using a Sequence
-- Caching sequence values in the memory give faster access to these values;
-- Gaps in sequence value can occur when
a rollback occurs
b the system crashes
c A sequence us used in another table;
5) alter sequence test increment by 10;
you can change all properties of the sequence except the start with .
6) remove sequence
drop sequence test;
2 index
1) how are indexes created
Automatically : a unique index is created automatically when you create primary key or
unique constraint in a table definition,
Manually: user can create nounique index on column to speed up access to the rows.
create index testindex on autoer(lanme);
2) When to Create an index
ypu should create an index if:
. a column contains a wide range of values
. a column contains a large number of null values
. one or more columns are frequently used together in where clause or a join condition;
. The table is large and most queries are expected to retrieve less than 2 to 4 percent
of the rows;
3) When not to create an index
this usually not worth creating an index if:
. the table is small
. The columns are not often used as a condition in the query.
. Most queries are expected to retrieve more than 2 to 4 percent of the rows in the
table
. the indexed columns are referenced as part of an expression.
4)Confirming indexes
. The user_indexes data dictionary view contains the name of the index and tis uniquess
. the user_ind_columns view contains the index name,the table name,and the column name.
select ic.index_name,ic_column_name,ic.column_position,ic_col_pos,ix.uniqueness
from user_indexed ix,user_ind_columns ic
where ic.index_name=ix.index_name
and ic.table_name='employees';
5)基于函数的索引
. a function-based index is an index based on expressions
. The index expression is built form table columns,constraints,SQL functions and user-
defined functions
create index testindex2
on autors (upper(au_fname));
select * from authors
where upper(au_fname) like 'B%';
6) remoe index
drop index index_name;
3 synonyms
Simplify access to objects by creating a synonym
. Ease referring to a table ownerd by anther user
. Shorten lengthy object names;
create [publi] synonym synonym for object;
1 pl/sql 集合 处理单列多行数据库,使用的类型为标量类型
1) 索引表
type ename_table_type is table of emp.ename%type
index by binary_integer;
ename_table ename_table_type;
begin
select ename into ename_table(-1) from emp
where empno=&no;
dbms_output.put_line('雇员名:'||ename_table(-1));
end;
set serveroutput no
declare
type area_table_type is table of number
index by varchar2(10);
rea_table area_table_type;
begin
area_table('beijing'):=1;
area_table('shanghai'):=2;
area_table('guangzhou'):=3;
dbms_output.put_line(area_table.first);
dbms_output.put_line(area_table.last);
end;
2) 嵌套表
索引表类型不能作为累得数据类型使用,但是嵌套表可以作为表类的数据类型使用。
当使用嵌套表元素时,必须先用其构造方法初始化其嵌套表:
a 在pl/sql 块中使用嵌套表
declare
type ename_table_type is table of emp.ename%type;
ename_table ename_table_type;
begin
ename_table:=eanme_table_type('2','2','3');
select ename into ename table(2) from emp where empno=&no;
dbms_ouput.put_line(ename_table(2));
end;
b 在表中使用嵌套表
create type phone_type is table of varchar2(20);
create table employee(
id number (4),name varchar2(10),sal number(6,2),
phone phone_type
)nested table phone store as phone_table;
-- 为嵌套表插入数据
insert into employee values(2,'scott',200,phone_type('2222','333333'));
--检索嵌套表累得数据
set erveroutput on
declare
phone_table phone_type;
begin
select phone into phone_table
from employee where id=1;
for i in 1..phone_table.count loop
dbms_output.put_line(phone_table(i));
end loop;
end;
-- 更新嵌套表列的数据
delcare
phone_table phone_type:=('44444','555555');
begin
update employee set phone=phone_table
where id=1;
end;
3) 变长数组
在使用varray 时必须指定最大个数,和数据类型,在使用其元素时必须进行初始化
type ename_table_type is varray(20) of emp.ename%type;
ename_table ename_table_type:=ename_table_type('1','2');
-- 在快中使用varray
declare
type ename_table_type is varray(20) of emp.ename%type;
ename_table ename_table_type:=ename_table_type('mary');
begin
select ename into ename_table(1) form emp
where empno=$no;
end;
--在表列中使用varray
create type phone type is varray(20) of varchar2(20);
create table employee(
id number(4),name varchar2(10),
sal number(6,2),phone phone_type);
3)记录表
记录表结合了记录和集合的优点
declare
type emp_table_type is table of emp%rowtype
index by binary_integer;
emp_table emp_table_type;
begin
select * from into emp_table(1) from emp
where empno=&no;
dbms_output.put_line(emp_table(1).ename);
end;
4)多维集合
1 多级varray
declare
--define 一维集合
type al_array_type is varray(10) of int;
--定义二维集合
type nal_varray_type is varray(10) of a1_varray_type;
--初始化二维集合
nvl nal_varray_type:=nal_varray_type(
a1_varray_type(1,2),
a1_varray_type(2,3)
)
beign
for i in 1..nal_varray_type.count loop
for j in 1..a1_array_type.count loop
dbms_out.putline(nvl(i)(j));
end loop;
end loop;
end;
2 使用多级嵌套表
table a1_table_type is table of int;
table nvl_table_type is table of a1_table_type;
nvl nvl_table_type:=nvl_table_type(
a1_table_type(1,2),
a1_table_type(2,3)
);
2 集合方法
1) exist
if ename_table.exists(1) then
ename_table(1):='scott';
2) count 返回当前集合变量中的元素总个数
ename_table.count
3) limit 返回集合元素的最大个数 只有varray 有
4)first and last
ename_table.first
ename_table.last
5) prior 和next
ename_table.prior(5); --返回元素5的前一个
ename_table.next(5); -- 后一个
6) extend
使用于varray 和 嵌套表。
extend add a null value
extend (n) add n null value
extend (n,i)add n i value
declare
type ename_table_type is varray(20) of varchar2(20);
ename_table ename_table_type;
begin
ename_table:=ename_table_type('mary');
ename_table.extend(5,1);
dbms_output.put_line(ename_table.count);
end;
7) trim
trim remove one element from the tail of the collection.
trim(n) remove n element from the tail of the colleciton.
8)delete
delete: delete all the elements
delete(n) :delete the nth elements
delete(m,n): delete the elements from m to n
3 集合赋值
1)将一个集合的数据赋值给另一个集合.clear the destination collectins and set the original collection
delcare
type name_varray_type is varray(4) of varchar2(10);
name_array1 name_varray_type;
name_array2 name_varray_type;
begin
name_array1:=name_varray_type('scott','smith');
name_array2:=name_array_type('a','b','c');
name_array1:=name_array2;
end;
type name_array1_type is varray(4) of varchar2(10);
type name_array2_type is varray(4) of varchar2(10);
name_array1 name_array1_type;
name_array2 name_array2_type;
具有相同的数据类型,单具有不同的集合类型不能构赋值
2) 给集合赋城null 值
可以使用delete 或 trim
也可以使用 空集合赋给目表集合
type name_varray_type is varray(4) of varchar2(10);
name_array name_varray_type;
name_empty name_varray_type;
name_array:=name_varray_type('1','2');
name_array:=name_empty;
3) 使用集合操作赋和比较集合都是10g 的内容,p176 先略过。
4 批量绑定
执行单词sql 操作能传递所有集合元素的数据。
1 forall 语句
用于insert update 和delete操作。在oracle9i 中forall 语句必须具有连续的元素
1) using forall on insert
declare
type id_table_type is table of number(6)
index by binary_integer;
type name_table_type is table of varchar2(2)
index by binary integer;
id_table id_table_type;
name_table name_table_type;
begin
for i in 1..10 loop
id_table(i):=i;
name_table(i):='Name'||to_char(i);
end loop;
forall i in 1..id_table.count
insert into demo demo values(id_table(i),name_table(i));
end;
2)using forall on using update
forall i in 1..id_table.count
upate demo set name:=name_table(i)
where id:=id_table(i);
3)using forall on using delete
forall i in 1..id_table.count
delete from demo where id:=id_table(i);
4) using forall on part of the collection
for i in1..10 loop
id_table(i):=i;
name_table(i):="name"||to_char(i);
end loop;
forall i in 8..10 l
insert into demo values(id_table(i),name_table(i));
2 bulk collect
is fit for select into ,fetch into and dml clause
1) using bulk collect
declares
type emp_table_type is table of emp%rowtype
index by binary_integer;
emp_table emp_table_type;
begin
select * bulk collect into emp_table
from emp where deptno=&no;
for i in 1..emp_tablee.count loop
dbms_output.put_line(emp_table(i).ename);
end loop;
2) 在dml 的返回字句使用bulk collect 字句
declare
type ename_table_type is table of emp.ename%type;
ename_table ename_table_type;
begin
deletee from emp where deptno=&no
returning ename bulk_collect into ename_table;
for i in 1..ename_table.count loop
dbms_output.put(ename_table(i));
end loop;
end;
end;
end;
1Why Use Views
to restrict data access
to make complex query easy
to provide data independence
to provide defferent view of the same data
2 Creating a View
1)create [or replace] [force|noforce] view view
as subquery
force : create view wether the referenced object existed or not
desc view_name;
2)create a view by using column aliases in the subquery
create view salv50
as select employee_idIO_NUMBER,last_name NAME,slaary*12 ANN_SALARY
from employees
where department_id=50;
3 Modigy a View
1) Modigy the emplvu80 view by using create or replace view clause.Add an alias for each
column name;
create or replace view empvu80
(id_number,name,sal,department_id)
as select employee_id,first_name||" "||last_name,salary.department_id
from employees
where department_id=80;
column aliases in the create view clause are listed in the same order as the columns in
the subquery
note : alter view_name is not a valid command.
4 Create a Complex View
Create a complex view that contains group functions to display values from two tables
create view dept_sum_vu
(name,minsal,maxsal,avgsal)
as
select d.department_name,min(e.salary),max(e.salary),avg(e.salary)
from employees e,departments d
where e.department_id=d.department_id
group by d.department_name;
5 Rules for performs DML operaton on a view
1) You can perform DML operation on simple views
2) You can not romove a row if the view contains the following:
--group functions
--a group by clause
--the distince keyword
-- rownum keyword
-- column defined by expressions
6 Using the with check option Clause
1) you can ensure that dml operatons performed on the view stay within the domain of the
view by using the with check option clause.
creaate view test1
as
select * from emp where qty>10;
with check option;
update testview1 set qty=10
where ster_id=6830;
--when you doing the following update operation
update testview1 set qty=5 where id=10;
-- an error will report
--you violate the where clause
2)Any attempt to change the department number for any row in the view fails because it
violates the with check option constraint
create or replace view empvu20
as
select * where department_id=20
with check option constriant empvu20_ck;
7 Denying DML Operations
1 You can ensure that no dml operations occur by adding the with read only option to your
view definition.
2)Any attempt to a DML on any row in the view resuls in an oralce server error.
8 remove veiw
drop view_name
9 inline view
1) an inline view is a subquery with an alias that you can use within a sql statement.
2) a named subquery in the from clause of the main query is an exqmple of an inline view
3) an inline view is not a schema object.
10 Top-N Analysis
1)Top_N querise ask for the n largest or smallest values of a column.
2)Both largest values and smallest values sets considered Top-N queries
select * from (select ster_id,qty from sales);
example
To display the top three earner names and salaries from the employees
select rownum as rank,last_name,salary
from (select last_anme,slary from employee
order by slary desc)
where rownum<=3;
1 pl/sql 集合 处理单列多行数据库,使用的类型为标量类型
1) 索引表
type ename_table_type is table of emp.ename%type
index by binary_integer;
ename_table ename_table_type;
begin
select ename into ename_table(-1) from emp
where empno=&no;
dbms_output.put_line('雇员名:'||ename_table(-1));
end;
set serveroutput no
declare
type area_table_type is table of number
index by varchar2(10);
rea_table area_table_type;
begin
area_table('beijing'):=1;
area_table('shanghai'):=2;
area_table('guangzhou'):=3;
dbms_output.put_line(area_table.first);
dbms_output.put_line(area_table.last);
end;
2) 嵌套表
索引表类型不能作为累得数据类型使用,但是嵌套表可以作为表类的数据类型使用。
当使用嵌套表元素时,必须先用其构造方法初始化其嵌套表:
a 在pl/sql 块中使用嵌套表
declare
type ename_table_type is table of emp.ename%type;
ename_table ename_table_type;
begin
ename_table:=eanme_table_type('2','2','3');
select ename into ename table(2) from emp where empno=&no;
dbms_ouput.put_line(ename_table(2));
end;
b 在表中使用嵌套表
create type phone_type is table of varchar2(20);
create table employee(
id number (4),name varchar2(10),sal number(6,2),
phone phone_type
)nested table phone store as phone_table;
-- 为嵌套表插入数据
insert into employee values(2,'scott',200,phone_type('2222','333333'));
--检索嵌套表累得数据
set erveroutput on
declare
phone_table phone_type;
begin
select phone into phone_table
from employee where id=1;
for i in 1..phone_table.count loop
dbms_output.put_line(phone_table(i));
end loop;
end;
-- 更新嵌套表列的数据
delcare
phone_table phone_type:=('44444','555555');
begin
update employee set phone=phone_table
where id=1;
end;
3) 变长数组
在使用varray 时必须指定最大个数,和数据类型,在使用其元素时必须进行初始化
type ename_table_type is varray(20) of emp.ename%type;
ename_table ename_table_type:=ename_table_type('1','2');
-- 在快中使用varray
declare
type ename_table_type is varray(20) of emp.ename%type;
ename_table ename_table_type:=ename_table_type('mary');
begin
select ename into ename_table(1) form emp
where empno=$no;
end;
--在表列中使用varray
create type phone type is varray(20) of varchar2(20);
create table employee(
id number(4),name varchar2(10),
sal number(6,2),phone phone_type);
3)记录表
记录表结合了记录和集合的优点
declare
type emp_table_type is table of emp%rowtype
index by binary_integer;
emp_table emp_table_type;
begin
select * from into emp_table(1) from emp
where empno=&no;
dbms_output.put_line(emp_table(1).ename);
end;
4)多维集合
1 多级varray
declare
--define 一维集合
type al_array_type is varray(10) of int;
--定义二维集合
type nal_varray_type is varray(10) of a1_varray_type;
--初始化二维集合
nvl nal_varray_type:=nal_varray_type(
a1_varray_type(1,2),
a1_varray_type(2,3)
)
beign
for i in 1..nal_varray_type.count loop
for j in 1..a1_array_type.count loop
dbms_out.putline(nvl(i)(j));
end loop;
end loop;
end;
2 使用多级嵌套表
table a1_table_type is table of int;
table nvl_table_type is table of a1_table_type;
nvl nvl_table_type:=nvl_table_type(
a1_table_type(1,2),
a1_table_type(2,3)
);
2 集合方法
1) exist
if ename_table.exists(1) then
ename_table(1):='scott';
2) count 返回当前集合变量中的元素总个数
ename_table.count
3) limit 返回集合元素的最大个数 只有varray 有
4)first and last
ename_table.first
ename_table.last
5) prior 和next
ename_table.prior(5); --返回元素5的前一个
ename_table.next(5); -- 后一个
6) extend
使用于varray 和 嵌套表。
extend add a null value
extend (n) add n null value
extend (n,i)add n i value
declare
type ename_table_type is varray(20) of varchar2(20);
ename_table ename_table_type;
begin
ename_table:=ename_table_type('mary');
ename_table.extend(5,1);
dbms_output.put_line(ename_table.count);
end;
7) trim
trim remove one element from the tail of the collection.
trim(n) remove n element from the tail of the colleciton.
8)delete
delete: delete all the elements
delete(n) :delete the nth elements
delete(m,n): delete the elements from m to n
3 集合赋值
1)将一个集合的数据赋值给另一个集合.clear the destination collectins and set the original
collection
delcare
type name_varray_type is varray(4) of varchar2(10);
name_array1 name_varray_type;
name_array2 name_varray_type;
begin
name_array1:=name_varray_type('scott','smith');
name_array2:=name_array_type('a','b','c');
name_array1:=name_array2;
end;
type name_array1_type is varray(4) of varchar2(10);
type name_array2_type is varray(4) of varchar2(10);
name_array1 name_array1_type;
name_array2 name_array2_type;
具有相同的数据类型,单具有不同的集合类型不能构赋值
2) 给集合赋城null 值
可以使用delete 或 trim
也可以使用 空集合赋给目表集合
type name_varray_type is varray(4) of varchar2(10);
name_array name_varray_type;
name_empty name_varray_type;
name_array:=name_varray_type('1','2');
name_array:=name_empty;
3) 使用集合操作赋和比较集合都是10g 的内容,p176 先略过。
4 批量绑定
执行单词sql 操作能传递所有集合元素的数据。
1 forall 语句
用于insert update 和delete操作。在oracle9i 中forall 语句必须具有连续的元素
1) using forall on insert
declare
type id_table_type is table of number(6)
index by binary_integer;
type name_table_type is table of varchar2(2)
index by binary integer;
id_table id_table_type;
name_table name_table_type;
begin
for i in 1..10 loop
id_table(i):=i;
name_table(i):='Name'||to_char(i);
end loop;
forall i in 1..id_table.count
insert into demo demo values(id_table(i),name_table(i));
end;
2)using forall on using update
forall i in 1..id_table.count
upate demo set name:=name_table(i)
where id:=id_table(i);
3)using forall on using delete
forall i in 1..id_table.count
delete from demo where id:=id_table(i);
4) using forall on part of the collection
for i in1..10 loop
id_table(i):=i;
name_table(i):="name"||to_char(i);
end loop;
forall i in 8..10 l
insert into demo values(id_table(i),name_table(i));
2 bulk collect
is fit for select into ,fetch into and dml clause
1) using bulk collect
declares
type emp_table_type is table of emp%rowtype
index by binary_integer;
emp_table emp_table_type;
begin
select * bulk collect into emp_table
from emp where deptno=&no;
for i in 1..emp_tablee.count loop
dbms_output.put_line(emp_table(i).ename);
end loop;
2) 在dml 的返回字句使用bulk collect 字句
declare
type ename_table_type is table of emp.ename%type;
ename_table ename_table_type;
begin
deletee from emp where deptno=&no
returning ename bulk_collect into ename_table;
for i in 1..ename_table.count loop
dbms_output.put(ename_table(i));
end loop;
end;
end;
end;
1 What are Constrains
1) Constrains enforce on the table level
2) Constrains the deletion of a table if there are dependencies
2 Constrain Guidelines
1) Name a constraint or the oracle generate a name by the sys_cn format
2) Create a constraint either
--At the same time as the table is created.or
--After the table has been created
3)Define a constraint at the column or table level
4)view constraint in the data dictionary
3 Crete a constraint
create table test2
(id int not null,-- column level
lname varchar(20),
fname varchar(20),
constraint uk_test2_1 unique(lname,fname))--table level
4 The not null Constraint
create table employees(
employee_id number(6),
last_name varchar2(25) not null --system named
hire_date DATE
constraint emp_hire_date not null --User named
5Foreign key
create table test3
(rid int,
name varchar(30),
constraint fk_test3_1 foreign key(rid) reference test2(id));
froeign key constraint keywords
foreign key :Define the column in thee child table at the table constrain level.
references :Identifies the table and column in the parent table.
on delete cascade: Delete the dependent rows in the child table when a row in the
parent table is deleted
on delete set null:Convert the dependent foreign key values to null when a row in the
parent table is deleted.
--parent table referenced table
--child table refernce other table
6 The check Constraint
Define a condition that each row must be satify
alter table test3
add constrain ch_test3 check(name like 's%')
7 Dropping a Constraint
1) Remove the manager constraint form the employee table
alter table test3
drop constriant test3_manager_fk
2) Remove the primary key constraint on the departments table and drop the associated
foreign key constraint on the employees.department_id column
alter table departments
drop primary key cascade
8 Disabling and enable Constraints
1)Execute the disable clause of the alter table statment to deactive an integrity
constraint
2)Apply the cascade option to disable dependent integrity constrints
alter table employees
disable constraint emp_emp_id_pl cascade
3) enabling Constraints
.Active an integrity constraint currently disabled in the table definition by using the
enable clause.
alter table employees
enable constraint emp_emp_id_pk;
a unique or a primary index is automatically created if you enable a unique key or a
primary key constraint
8 View Constraints
select constraint_name,constriant_type,serch_condition
from user_constraints
where table_name='employees'
9 view the columns associated with constraints
select constraint_name,column_name
from user_cons_columns
where table_name='employees'
OpenSessionInView
Created by
potian. Last edited by
admin 61 days ago. Viewed 181 times.
[edit]
[attach]
Hibernate的Lazy初始化1:n关系时,你必须保证是在同一个Session内部使用这个关系集合,不然Hiernate将抛出例外。
另外,你不愿意你的DAO测试代码每次都打开关系Session,因此,我们一般会采用OpenSessionInView模式。
OpenSessionInViewFilter解决Web应用程序的问题
如果程序是在正常的Web程序中运行,那么Spring的
OpenSessionInViewFilter能够解决问题,它:
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
SessionFactory sessionFactory = lookupSessionFactory();
logger.debug("Opening Hibernate Session in OpenSessionInViewFilter");
Session session = getSession(sessionFactory);
TransactionSynchronizationManager.bindResource(sessionFactory,
new SessionHolder(session));
try {
filterChain.doFilter(request, response);
}
finally {
TransactionSynchronizationManager.unbindResource(sessionFactory);
logger.debug("Closing Hibernate Session in OpenSessionInViewFilter");
closeSession(session, sessionFactory);
}
}
可以看到,这个Filter在request开始之前,把sessionFactory绑定到TransactionSynchronizationManager,和这个SessionHolder相关。这个意味着所有request执行过程中将使用这个session。而在请求结束后,将和这个sessionFactory对应的session解绑,并且关闭Session。
为什么绑定以后,就可以防止每次不会新开一个Session呢?看看HibernateDaoSupport的情况:
publicfinal void setSessionFactory(SessionFactory sessionFactory) {
this.hibernateTemplate = new HibernateTemplate(sessionFactory);
}
protectedfinal HibernateTemplate getHibernateTemplate() {
return hibernateTemplate;
}
我们的DAO将使用这个template进行操作:
publicabstract class BaseHibernateObjectDao
extends HibernateDaoSupport
implements BaseObjectDao {protected BaseEntityObject getByClassId(finallong id) {
BaseEntityObject obj =
(BaseEntityObject) getHibernateTemplate()
.execute(new HibernateCallback() {
publicObject doInHibernate(Session session)
throws HibernateException {
return session.get(getPersistentClass(),
newLong(id));
}
});
return obj;
}
public void save(BaseEntityObject entity) {
getHibernateTemplate().saveOrUpdate(entity);
}
public void remove(BaseEntityObject entity) {
try {
getHibernateTemplate().delete(entity);
} catch (Exception e) {
thrownew FlexEnterpriseDataAccessException(e);
}
}
public void refresh(final BaseEntityObject entity) {
getHibernateTemplate().execute(new HibernateCallback() {
publicObject doInHibernate(Session session)
throws HibernateException {
session.refresh(entity);
returnnull;
}
});
}
public void replicate(finalObject entity) {
getHibernateTemplate().execute(new HibernateCallback() {
publicObject doInHibernate(Session session)
throws HibernateException {
session.replicate(entity,
ReplicationMode.OVERWRITE);
returnnull;
}
});
}
而HibernateTemplate试图每次在execute之前去获得Session,执行完就力争关闭Session
publicObject execute(HibernateCallback action) throws DataAccessException {
Session session = (!this.allowCreate ?
SessionFactoryUtils.getSession(getSessionFactory(),
false) :
SessionFactoryUtils.getSession(getSessionFactory(),
getEntityInterceptor(),
getJdbcExceptionTranslator()));
boolean existingTransaction =
TransactionSynchronizationManager.hasResource(getSessionFactory());
if (!existingTransaction && getFlushMode() == FLUSH_NEVER) {
session.setFlushMode(FlushMode.NEVER);
}
try {
Object result = action.doInHibernate(session);
flushIfNecessary(session, existingTransaction);
return result;
}
catch (HibernateException ex) {
throw convertHibernateAccessException(ex);
}
catch (SQLException ex) {
throw convertJdbcAccessException(ex);
}
catch (RuntimeException ex) {
// callback code threw application exception
throw ex;
}
finally {
SessionFactoryUtils.closeSessionIfNecessary(
session, getSessionFactory());
}
}
而这个SessionFactoryUtils能否得到当前的session以及closeSessionIfNecessary是否真正关闭session,端取决于这个session是否用sessionHolder和这个sessionFactory在我们最开始提到的TransactionSynchronizationManager绑定。
publicstatic void closeSessionIfNecessary(Session session,
SessionFactory sessionFactory)
throws CleanupFailureDataAccessException {
if (session == null ||
TransactionSynchronizationManager.hasResource(sessionFactory)) {
return;
}
logger.debug("Closing Hibernate session");
try {
session.close();
}
catch (JDBCException ex) {
// SQLException underneath
thrownew CleanupFailureDataAccessException(
"Cannot close Hibernate session", ex.getSQLException());
}
catch (HibernateException ex) {
thrownew CleanupFailureDataAccessException(
"Cannot close Hibernate session", ex);
}
}
HibernateInterceptor和OpenSessionInViewInterceptor的问题
使用同样的方法,这两个Interceptor可以用来解决问题。但是关键的不同之处在于,它们的力度只能定义在DAO或业务方法上,而不是在我们的Test方法上,除非我们把它们应用到TestCase的方法上,但你不大可能为TestCase去定义一个接口,然后把Interceptor应用到这个接口的某些方法上。直接使用HibernateTransactionManager也是一样的。因此,如果我们有这样的测试:
Category parentCategory = new Category ();
parentCategory.setName("parent");
dao.save(parentCategory); Category childCategory = new Category();
childCategory.setName("child");
parentCategory.addChild(childCategory);
dao.save(childCategory);
Category savedParent = dao.getCategory("parent");
Category savedChild = (Category ) savedParent.getChildren().get(0);
assertEquals(savedChild, childCategory);
将意味着两件事情:
- 每次DAO执行都会启动一个session和关闭一个session
- 如果我们定义了一个lazy的关系,那么最后的Category savedChild = (Category ) savedParent.getChildren().get(0);将会让hibernate报错。
解决方案
一种方法是对TestCase应用Interceptor或者TransactionManager,但这个恐怕会造成很多麻烦。除非是使用增强方式的AOP.我前期采用这种方法(Aspectwerkz),在Eclipse里面也跑得含好。
另一种方法是在TestCase的setup和teardown里面实现和Filter完全一样的处理,其他的TestCase都从这个TestCase继承,这种方法是我目前所使用的。
Jolestar补充:openSessionInView的配置方法:
<filter>
<filter-name>opensession</filter-name>
<filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
<init-param>
<param-name>singleSession</param-name>
<param-value>false</param-value>
</init-param>
</filter>
1 Table in the Oracle Database
1) User Tables:
a Are a collection of tables created and maintained by the user
b Contain user information
2) Data Dictionary
a is a collection of table created and maintained by the Oracle Server
b Contain database information
2 Querying the Data Dictionary
1)see the names of the table owned by the user
select table_name from user_tables;
2) view distinct object types ownered by the user
select distinct object_type from user_object;
3) view tables ,view ,synonyms and sequences owned by the user
select * from user_catalog
3 Creating a Table by Ussing a Subquery Syntax
create table tt3
as
select * from authors
4 Teh alter table Statement
1) Add a new column
alter table tt2
add(fname varchar2(20) default 'unkonown',
address varchar2(30) null);
2)Modigying a Column's data type size and default value
alter table dept80
modigy (last_name varchr2(30))
A change to thee default value affects onlly subsequent insertion to the table
3) drop a column
alter table dept80
drop column job_id;
The set unseed Option
a you use the set unused optoin to mark one or more columns as unused
b you use the drop unused colimns options to remove the columns that are marked as
as unused
alter table tt2
set unused colun fnamel;
alter table table
drop unused columns
5 Dropping a Table
1) All data and structure in the table is deleted
2) Any pending transaction are committed
3) All indexes are dropped
4) You cannot roll back the drop table statement
6 Changing the Name of an Object
rename dept to detail_dept;
you must be the owner of the object
7 Truncate a Table
Remove all rows from the table
release the storage space used by that table
you cannot rollback row when using truncate
alternatly ,you can remove row by using delete statement
1 Data Manipulation Language
1) A DML statement is executed when you:
add new rows to a table
modify existing row in a table
remove existing rows from a table
2) A transaction consist a collection dml statements form a logic unit of work
2 Using Explicit Default Values
1) default with insert
insert into departments
values(200,'ddd',default)
2) default with update
update departments
set manager_id=default where department_id=10
3 The Merge Statement
1)Provide the ability to conditionaly update or insert data into database
2)Perform a update if the row exists and an insert if it is a new row
a Avoid update separatly
b increase performance and ease of use
c is useful in data warehousing application
example
merge into copy_emp c
using employees e
on (c.employee_id=e.employee_id)
when mathched then
update set
c.first_name=e.first_name
c.last_name=e.last_name
..............
c.department_id=e.department_id
when not matched then
insert values(e.employeeid,e.first_name,......e.department_id);
4 Database Transactions
1)Begin when the first dml statement is executed
2)end with one of the following events
a a commit or rollback statement is issued;
b a ddl or dcl statement execute (commit automatically)
c the user exist isqllplus
d the system crashes
3) advantage of commit and rollback statemnt
With commit and rollback statement ,you can
a ensure data consistence
b Preview data change before making change permant
c group logic relate operatons
5 State of The Data Before commit or rollback
1) the previous state of the data can be recovered
2) The current user can review the result of the dml operation by using the select statment
3) other user can not view the result of the dml
4) the affected was locked ,other user cannot change the data within the affecteed row
6 Read Consistency
1) Read consistency guarantees a consistent view of the data at all times
2) Changes made by one user do not confilict with changes made by another user
3) Read consistency ensures that on the same data
a Readers do not wait for writers
b Writers do not wait for readers
7Locking
1) Prevent destructive interaction between concurrent transactions
2) Reqire no user action
3) Automatically use the lowest level of restrictiveness
4) Are held for the duration of the transaction
5) Are of two types:explicit locking an implicit locking
8 Implicit Locking
1)Two lock modes
a Exclusive :Locks out other users
b Share: Allows other users to accesss
2)High level of data concurrency
a DML:Table share,row exclusive
b Queries: No locks required
c DDL:Protects object definitions
3)Locks held until commit or rollback