Orcal学习

sqlplus有几种登陆方式 比如:
1.C: > sqlplus "/as sysdba" --以操作系统权限认证的oracle sys管理员登陆
2.C: > sqlplus /nolog --不在cmd或者terminal当中暴露密码的登陆方式
SQL> conn /as sysdba
&
SQL> conn sys/password as sysdba

3.C: > sqlplus scott/tiger --非管理员用户登陆
4.C: > sqlplus scott/tiger@orcl --非管理员用户使用tns别名登陆
5.C: > sqlplus sys/password@orcl as sysdba --管理员用户使用tns别名登陆
6.C: > sqlplus --不显露密码的登陆方式
Enter user-name:sys
Enter password:password as sysdba --以sys用户登陆的话 必须要加上 as sysdba 子句

sql*plus常用命令
show user 显示当前用户
conn system/oracle@orcl 使用指定用户连接
disc /disconn/disconnect 断开与当前数据库的连接
pssw 修改密码
exit 断开与数据库的连接,同时退出sql*plus
@ d:a.sql 或 start d:a.sql 运行SQL脚本
edit d:a.sql 编辑指定SQL脚本
将屏幕上的内容输出到指定文件中
spool d:..sql;
select * form emp;
spool off;
select * form emp where job="&job" 执行该语句时,&变量需要用户输入

oracle用户管理
create user 用户名 identified by 密码//新用户是没有任何权限的
password 用户名或passw //修改密码
drop user 用户名 [cascade]//删除用户,加参数把用户及表一同删除
用户管理综合案例
conn xiaoming/oracle
show user
conn system/oracle
grant connect to xiaoming
conn xiaoming/oracle
connect不是权限,而是角色,现在说下对象权限,现在要做这么件事情:
* 希望xiaoming用户可以去查询emp表
* 希望xiaoming用户可以去查询scott的emp表
grant select on scott.emp to xiaoming
* 希望xiaoming用户可以去修改scott的emp表
grant update on scott.emp to xiaoming
* 希望xiaoming 用户可以去修改/删除,查询,添加scott的emp表
grant all on scott.emp to xiaoming
* scott希望收回xiaoming对emp表的查询权限
revoke select on scott.emp from xiaoming
grant select on emp to xiaoming with grant option xiaoming//可以查询scott的emp表/并且可以把这个权限传递给别人。如果把xiaoming对emp表的查询权限回收,那么xiaohong会受到诛连
with admin option用于系统权限授权,用户已经授予其他用户或角色的此系统权限不会因传播无效.with grant option用于对象授权,权限会因传播而失效。
使用profile管理用户口令,profile是口令限制,资源限制的命令集合,当建立数据库时,oracle会自动建立名称为default的profile。当建立用户没有指定profile选项时,那么oracle就会将default分配给用户。
SQL> create profile lock_account limit failed_login_attempts 3 password_lock_time 2;//指定scott这个用户最多只能尝试3次登陆,锁定时间为2天,让我们看看怎么实现。
SQL> alter user scott profile lock_account;
SQL> alter user scott account unlock;//给账户(用户)解锁
drop profile password_history 【casade】//文件删除后,用这个文件去约束的那些用户通通也都被释放了。加了casade,就会把级联的相关东西也给删除掉

oracle 表的管理
varchar2(20) //长度可变,最多容纳4000个字符。
clob(character large object) //字符型大对象,最多容纳4g
number //范围-10的38次方到10的38次方,可以表示整数,也可以表示小数
date //包含年月日和时分秒 
timestamp //这是oracle9i对date数据类型的扩展。可以精确到毫秒。
blob //二进制数据,可以存放图片/声音4g
创建表:
--学生表
create table student (
xh number(4), --学号
xm varchar2(20), --姓名
sex char(2), --性别
birthday date, --出生日期
sal number(7,2) --奖学金
);
--班级表
create table class(
classid number(2),
cname varchar2(40)
);
create table goods(
goodsId char(8) primary key, --主键
goodsName varchar2(30),
unitprice number(10,2) check(unitprice>0),
category varchar2(8),
provider varchar2(30)
);
create table customer( 
customerId char(8) primary key, --主键
name varchar2(50) not null, --不为空
address varchar2(50),
email varchar2(50) unique, --唯一
sex char(2) default '男' check(sex in ('男','女')), -- 一个char能存半个汉字,两位char能存一个汉字
cardId char(18)
);
create table purchase( 
customerId char(8) references customer(customerId),
goodsId char(8) references goods(goodsId),
nums number(10) check (nums between 1 and 30)
);
alter table tb_dept add constraint tb_dept primary key (deptno);//添加主键约束
修改表:
sql>alter table student add (classid number(2));--添加一个字段
sql>alter table student modify (xm varchar2(30));--修改一个字段的长度
sql>alter table student modify (xm char(30));--修改字段的类型或是名字(不能有数据) 不建议做
sql>alter table student drop column sal;--删除一个字段 不建议做(删了之后,顺序就变了。加就没问题,应该是加在后面)
sql>rename student to stu;--修改表的名字 很少有这种需求
删除表:
sql>drop table student;
添加数据:
insert into student values ('a001', '张三', '男', '01-5 月-05', 10);//所有字段都插入数据--oracle中默认的日期格式‘dd-mon-yy’ ‘09-6 月-99’ 1999年6月9日
alter session set nls_date_format ='yyyy-mm-dd'//修改日期的默认格式(临时修改,数据库重启后仍为默认;如要修改需要修改注册表)
insert into student values ('a002', 'mike', '男', '1905-05-06', 10);//修改后,可以用我们熟悉的格式添加日期类型:
insert into student(xh, xm, sex) values ('a003', 'john', '女');//插入部分字段
insert into student(xh, xm, sex, birthday) values ('a004', 'martin', '男', null);//插入空值
select * from student where birthday is null;//查询student表里birthday为null的记录,怎么写sql呢?
select * from student where birthday is not null;//查询birthday不为null,则应该这样写:
修改数据:
update student set sex = '女' where xh = 'a001';//修改一个字段
update student set sex = '男', birthday = '1984-04-01' where xh = 'a001';//修改多个字段
select * from student where birthday is null;//修改含有null值的数据
删除数据:
delete from student; --删除所有记录,表结构还在,写日志,可以恢复的,速度慢。
savepoint a; --创建保存点
delete from student;
rollback to a; --恢复到保存点,一个有经验的dba,在确保完成无误的情况下要定期创建还原点。
drop table student; --删除表的结构和数据;
delete from student where xh = 'a001'; --删除一条记录;
truncate table student; --删除表中的所有记录,表结构还在,不写日志,无法找回删除的记录,速度快。

表查询
desc emp;//查看表结构
select * from dept;//查询所有列
set timing on/off;//打开显示操作时间的开关,在底部显示操作时间。
insert into tb_dept (deptno, dname, loc) select a.deptno, a.dname, a.loc from dept a;//表复制语句
select count (*) from emp;//统计
select ename, sal, job, deptno from emp;//查询指定列
select distinct deptno, job from emp;//如何取消重复行distinct
select deptno, job, sal from emp where ename = 'smith';//查询smith所在部门,工作,薪水
select sal*13+nvl(comm, 0)*13 "年薪" , ename, comm from emp;//nvl函数:为空时设置默认值 
select ename "姓名", sal*12 as "年收入" from emp;//使用列的别名
select ename || ' is a ' || job from emp;//连接字符串(||)
select * from emp where sal > 3000;
select ename,hiredate from emp where hiredate >'1-1 月-1982';
select ename,sal from emp where sal>=2000 and sal<=3000;
select ename,sal from emp where ename like 's%';
select ename,sal from emp where ename like '__o%';//如何显示第三个字符为大写o的所有员工的姓名和工资?
select * from emp where empno in (7844, 7839, 123, 456);
select * from emp where (sal > 500 or job = 'MANAGER') and ename like 'J%';
select * from emp order by deptno, sal desc;
select ename, (sal+nvl(comm,0))*12 "年薪" from emp order by "年薪" asc;//按年薪排序,使用列的别名排序,别名需要使用“”号圈中,英文不需要“”号
select sum(e.sal), avg(e.sal) from emp e;//所有员工的平均工资和工资总和
select ename, job, sal from emp e where sal = (select max(sal) from emp);//查询最高工资员工的名字,工作岗位
select avg(sal), max(sal), deptno from emp group by deptno;
select avg(sal), max(sal), deptno from emp group by deptno having avg(sal)< 2000;

oracle 事务
1.设置保存点 savepoint a
2.取消部分事务 rollback to a
3.取消全部事务 rollback
这个回滚事务,必须是没有commit前使用的;如果事务提交了,那么无论你刚才做了多少个保存点,都统统没用。如果没有手动执行commit,而是exit了,那么会自动提交。
SQL> savepoint a;
Savepoint created

SQL> delete from emp where empno=7782;
1 row deleted

SQL> commit;
Commit complete

SQL> rollback to a;
rollback to a
ORA-01086: 从未创建保存点 'A'
SQL>
只读事务
set transaction read only;//设置只读事务: 
commit;//提交

备份和恢复
导出表
exp userid=scott/oracle@orcl tables=(emp,dept) file=d:emp.dmp //导出自己的多个表
exp userid=system/oracle@orcl tables=(scott.emp,scott.dept) file=d:emp.emp //导出其它方案的表,则需要dba的权限或是exp_full_database的权限,比如system就可以导出scott的表
exp userid=scott/oracle@orcl tables=(emp) file=d:emp.dmp rows=n //导出表的结构
exp userid=scott/oracle@orcl tables=(emp) file=d:emp.dmp direct=y //使用直接导出方式,这种方式比默认的常规方式速度要快,当数据量大时,可以考虑使用这样的方法。这时需要数据库的字符集要与客户端字符集完全一致,否则会报错...
导出方案:指使用export工具导出一个方案或是多个方案中的所有对象(表,索引,约束...)和数据,并存放到文件中。
exp userid=scott/oracle@orcl owner=scott file=d:scott.dmp //导出自己的方案
exp userid=system/oracle@orcl owner=(system,scott) file=d:system.dmp //system 用户就可以导出任何方案
导出数据库:
exp userid=system/oracle@orcl full=y inctype=complete file=d:all.dmp //要求该用户具有dba的权限或者是exp_full_database权限
恢复(导入)
imp userid=scott/oracle@orcl tables=(emp) file=d:xx.dmp //导入自己的表
imp userid=system/oracle@orcl tables=(emp) file=d:xx.dmp touser=scott //导入表到其它用户,要求该用户具有dba的权限,或是imp_full_database
imp userid=scott/oracle@orcl tables=(emp) file=d:xx.dmp rows=n //只导入表的结构而不导入数据
imp userid=scott/oracle@orcl tables=(emp) file=d:xx.dmp ignore=y //如果对象(如比表)已经存在可以只导入表的数据
imp userid=scott/oracle@orcl file=d:xxx.dmp 导入自身的方案
imp userid=system/oracle@orcl file=d:xxx.dmp fromuser=system touser=scott //导入其它方案,要求该用户具有dba的权限
imp userid=system/oracle@orcl full=y file=d:xxx.dmp //导入数据库(相当于数据库迁移)

索引
select index_name, index_type from user_indexes where table_name = '表名';

pl/sql
pl/sql developer是用于开发pl/sql块的集成开发环境(ide),可以用来编写存储过程、函数、触发器、包等
块(block)是pl/sql的基本程序单元,编写pl/sql程序实际上就是编写pl/sql块,要完成相对简单的应用功能,可能只需要编写一个pl/sql块,但是如果想要实现复杂的功能,可能需要在一个pl/sql块中嵌套其它的pl/sql块。
块结构示
pl/sql块由三个部分构成:定义部分,执行部分,例外处理部分。
如下所示:
declare
/*定义部分——定义常量、变量、游标、例外、复杂数据类型*/
begin
/*执行部分——要执行的pl/sql 语句和sql 语句*/
exception
/*例外处理部分——处理运行的各种错误*/
end;
定义部分是从declare开始的,该部分是可选的;
执行部分是从begin开始的,该部分是必须的;
例外处理部分是从exception开始的,该部分是可选的。
实例
set serveroutput on; 
DECLARE
--定义字符串变量
v_ename varchar2(10); 
v_sal NUMBER(7,2);
BEGIN
--执行部分
select ename, sal into v_ename, v_sal from emp where empno=&empno; 
dbms_output.put_line('雇员名:'||v_ename||',薪水:'||v_sal);
EXCEPTION
--异常处理 
WHEN no_data_found THEN dbms_output.put_line('朋友,您的编号输入有误!');
end;
oracle pl/sql分类一 存储过程
实例:存储过程,可以输入雇员名,新工资,用来修改雇员的工资
CREATE PROCEDURE sp_update(uname VARCHAR2, newsal NUMBER) IS
BEGIN
update emp set sal=newsal where ename=uname;
END;
调用存储过程有两种方法:exec、call
--使用exec调用存储过程
SQL> exec sp_update('zhangsan', 888);
SQL> commit;
oracle pl/sql分类二 函数,函数头部必须包含return子句。而在函数体内必须包含return语句返回的数据。我们可以使用create function来建立函数。
create or replace 
function client_ip_address
return varchar2 is
begin
return dbms_standard.client_ip_address;
end;
调用:
SQL> var income NUMBER;
SQL> call annual_incomec('SCOTT') into:income;
SQL> print income;
oracle pl/sql分类三 包,包用于在逻辑上组合过程和函数,它由包规范和包体两部分组成。
1)、我们可以使用create package命令来创建包,如:
i、创建一个包sp_package
ii、声明该包有一个过程update_sal
iii、声明该包有一个函数annual_income

--声明该包有一个存储过程和一个函数
create package sp_package is
procedure update_sal(name varchar2, newsal number);
function annual_income(name varchar2) return number;
end;
2)、建立包体可以使用create package body命令给包sp_package实现包体
CREATE OR REPLACE PACKAGE BODY SP_PACKAGE IS
--存储过程
PROCEDURE UPDATE_SAL(NAME VARCHAR2, NEWSAL NUMBER) IS
BEGIN
UPDATE EMP SET SAL = NEWSAL WHERE ENAME = NAME;
COMMIT;
END;

--函数
FUNCTION ANNUAL_INCOME(NAME VARCHAR2) RETURN NUMBER IS
ANNUAL_SALARY NUMBER;
BEGIN
SELECT SAL * 12 + NVL(COMM, 0) INTO ANNUAL_SALARY FROM EMP WHERE ENAME = NAME;
RETURN ANNUAL_SALARY;
END;
END;
3)、如何调用包的过程或是函数
--调用存储过程
SQL> exec sp_package.update_sal('SCOTT', 8888);
--调用函数
var income NUMBER;
CALL sp_package.ANNUAL_INCOME('SCOTT') INTO:income;
print income;
oracle pl/sql 变量
编写分页过程,开发使用分页包
http://www.cnblogs.com/linjiqin/archive/2012/02/28/2372096.html

异常:oracle将异常分为预定义异常、非预定义异常和自定义异常三种。
--自定义异常
CREATE OR REPLACE PROCEDURE EX_TEST(SPNO NUMBER) IS
--定义一个异常
MYEX EXCEPTION;
BEGIN
--更新用户sal
UPDATE EMP SET SAL = SAL + 1000 WHERE EMPNO = SPNO;
--sql%notfound 这是表示没有update
--raise myex;触发myex
IF SQL%NOTFOUND THEN RAISE MYEX;
END IF;
EXCEPTION
WHEN MYEX THEN DBMS_OUTPUT.PUT_LINE('没有更新任何用户');
END;

创建/修改视图
1、创建视图
create view 视图名 as select 语句 [with read only]
2、创建或修改视图
create or replace view 视图名 as select 语句 [with read only]
3、删除视图
drop view 视图名

触发器
CREATE OR REPLACE TRIGGER MY_TGR
BEFORE INSERT ON TAB_USER
FOR EACH ROW--对表的每一行触发器执行一次
DECLARE
NEXT_ID NUMBER;
BEGIN
SELECT MY_SEQ.NEXTVAL INTO NEXT_ID FROM DUAL;
:NEW.ID := NEXT_ID; --:NEW表示新插入的那条记录
END;










原文地址:https://www.cnblogs.com/antonyhubei/p/5206124.html