Oracle 基本 以及 plsql 语句

Oracle

一、基本SQL语句

1、综述

基本SQL 语句分为DDL、DML、DCL和TCL 四种:
(1)DDL 数据定义语言 —————> 对表结构、索引和同义词的操作
(2)DML数据操作语言 —————> 表数据的增删改查
(3)DCL 数据控制语言 —————> 授权和收回权限
(4)TCL 事务控制语言 —————> commit、rollback、savepoint

2、DDL 数据定义语言

(1)表

A.创建
–创建表

create table tbl_person(
       pid number(11) primary key,
       pname varchar(20),
       psex varchar(4) not null,
       pposition varchar(20),
       constraint per_u unique (pname),
       constraint per_c check (psex in ('boy','girl'))
)
--constraint 对表字段添加约束 (uniquecheckprimary keyforeign key)

B.删除
–删除表

drop table tbl_person;

C.修改
–添加新字段
alter table tbl_person add page number(4);
–修改字段名
alter table tbl_person rename column page to age;
–修改字段数据类型
alter table tbl_person modify (age varchar(4));
–删除字段
alter table tbl_person drop column age;
–修改表名
rename tbl_person to t_person;
rename t_person to tbl_person;
–删除约束
alter table tbl_person drop constraint per_u;
–添加约束
alter table tbl_person add constraint per_u unique (pname);
–禁用约束
alter table tbl_person disable constraint per_u;
–启用约束
alter table tbl_person enable constraint per_u;

(2)索引

A.创建
–创建索引 感觉就是目录 根据某种顺序便于查找之类的

create index name_in on tbl_person(pid desc); 

B.删除
–删除索引

drop index  name_in;

(3)同义词

A.创建
–创建同义词 同义词就是给表或视图取一个别名

CREATE SYNONYM <synonym_name> for <tablename/viewname>

Eg:create synonym mm for emp;

B.删除
–删除同义词

drop  synonym  mm;

3、DML数据操作语言

(1)增删改——update

insert into tbl_person values(tbl_person_seq.nextval,'zhangsan','boy','snncjj');
insert into tbl_person values(tbl_person_seq.nextval,'lisi','boy','snncjj');

update tbl_person set pposition = 'ajkaj' where pid=5;

delete from tbl_person where pid=5;

(2)查—–query

select * from tbl_person;
select count(*)  from tbl_person;
select pname  from tbl_person where pid = 4;

一般查询

SELECT [DISTINCT] 
                        -- DISTINCT --表示隐藏重复的行
FROM 
[WHERE <条件>]   WHERE --按照一定的条件查找记录
[GROUP BY ]   GROUP BY --分组查找(需要汇总时使用)
[HAVING <条件>]                                             HAVING --分组的条件
[ORDER BY  [ASC|DESC]]  
                            -- ORDER BY --对查询结果排序

聚集函数—-只能放在select或者having下面
SUM –求和
AVG –求平均值
MAX –求最大值
MIN –求最小值
COUNT –求个数

子查询

SELECT <字段列表> from  where 字段 运算符(<SELECT 语句>);
eg:select * from emp where sal=(select max(sal) from emp);

Any 运算符

select * from emp where sal>ANY(select sal from emp where deptno=30) and deptno<>30;
--找出比deptno=30的员工最低工资高的其他部门的员工

ALL 运算符

select * from emp where sal>ALL(select sal from emp where deptno=30) and deptno<>30;
--找出比deptno=30的员工最高工资高的其他部门的员工

连接查询

SELECT <字段列表> from  WHERE table1.字段[(+)]=table2.字段[(+)]
eg:select empno,ename,dname from emp,dept where emp.deptno=dept.deptno;

分页—rownum

select * from emp where rownum<=10;--查询前10行记录
select * from emp where rownum<=3 and empno not in (
    select empno from emp where rownum<=3);     
    --查询第3到6行记录 

SELECT * FROM   
(  
SELECT A.*, ROWNUM RN   
FROM (SELECT * FROM TABLE_NAME) A   
WHERE ROWNUM <= 40  
)  
WHERE RN >= 21  

4、DCL 数据控制语言

(1)授权

GRANT <权限列表> to ;

(2)收回权限

REVOKE <权限列表> from <user_name>

5、TCL 事务控制语言

COMMIT 提交
– ROLLBACK 撤销数据更新 返回到事务开始时的状态 或者回退到保存点 注意:回退到更上层的保存点之后,下层的会失效
– SAVEPOINT 保存点

二、Oracle其他对象

1、视图

创建视图

CREATE [OR REPLACE] VIEW   AS  <SELECT 语句>;

删除视图

DROP VIEW  

2、序列

创建序列

CREATE SEQUENCE <sequencen_name> 
INCREMENT BY n
START WITH n
[MAXVALUE n][MINVALUE n]
[CYCLE|NOCYCLE]
[CACHE n|NOCACHE];

INCREMENT BY n --表示序列每次增长的幅度;默认值为1
START WITH n --表示序列开始时的序列号。默认值为1
MAXVALUE n --表示序列可以生成的最大值(升序)
MINVALUE n --表示序列可以生成的最小值(降序)
CYCLE --表示序列到达最大值后,在重新开始生成序列.默认值为 NOCYCLE
CACHE --允许更快的生成序列

使用序列

CURRVAL 返回序列的当前值.
注意在刚建立序列后,序列的CURRVAL值为NULL,所以不能直接使用。
可以先初始化序列:
方法:select .nextval from dual; 之后就可以使用CURRVAL属性了

NEXTVAL 返回序列下一个值;
可以表示记录ID的自增:
insert into tbl_person values(tbl_person_seq.nextval,’lisi’,’boy’,’snncjj’);

修改序列

ALTER SEQUENCE <sequencen_name> 
INCREMENT BY n
START WITH n
[MAXVALUE n][MINVALUE n]
[CYCLE|NOCYCLE]
[CACHE n|NOCACHE];

删除序列

DROP SEQUENCE <sequence_name> 

3、用户

创建用户

CREATE USER  [profile "DEFAULT"]
identified by "" [default tablespace "USERS"]

删除用户

DROP USER  CASCADE;

4、角色
创建角色

CREATE  ROLE    identified by ""

删除角色

DROP ROLE <role_name>

三、Pl/SQL

pl/sql 过程化SQL语言 是Oracle 数据库对标准数据库语言SQL的扩展,把数据库技术和过程化程序设计语言联系起来
简而言之 pl/sql就是可以过程化的操作SQL语句

1、Pl/SQL结构

DECLARE           --声明部分
   声明语句
BEGIN             --执行部分
   执行语句
EXCEPTION         --异常处理部分
   执行语句
END;

变量声明
<变量名> 类型 [:=初始值];
1、特殊类型======字段%type
eg: name emp.ename%type –表示name的类型和emp.ename的类型相同

2、表类型===========%rowtype
eg:test emp%rowtype
–表示test的类型为emp表的行类型;也有 .empno; .ename; .sal ;等属性
常量声明
<变量名> CONSTANT 类型:=初始值;
示例: pi constant number(5,3):=3.14;

全局变量声明
VARIABLE <变量名> 类型;
示例: VARIABLE num number;

使用全局变量
:<变量名>
示例:
:num:=100;
i=:num;

查看全局变量的值
print <变量名>
示例: print num;

赋值运算符: :=
示例: num := 100;
使用SELECT <列名> INTO <变量名> FROM <表名> WHERE <条件>
注意select into 语句的返回结果只能为一行;
示例:test emp%rowtype;
select * into test from emp where empno=7788;

用户交互输入
<变量>:=’&变量’
示例:
num:=#
注意oracle的用户交互输入是先接受用户输入的所有值后在执行语句;
所以不能使用循环进行用户交互输入;

条件控制语句
IF <条件1> THEN
语句
[ELSIF <条件n> THEN 注意是ELSIF
语句]
[ELSE
语句]
END IF;

循环控制语句
1.LOOP
LOOP
语句;
EXIT WHEN <条件>
END LOOP;

2.WHILE LOOP
WHILE <条件>
LOOP
语句;
END LOOP;

3.FOR
FOR <循环变量> IN 下限..上限
LOOP
语句;
END LOOP;

NULL 语句
null;
表示没有操作;

注释使用
单行注释: –
多行注释:/* ………………….*/

异常处理

EXCEPTION
WHEN <异常类型> THEN
语句;
WHEN OTHERS THEN
语句;
END;

2、过程

存储过程 类似函数,需要调用存储过程名称

定义:存储过程(Stored Procedure)是一组为了完成特定功能的 SQL 语句集,经编译后存储在数据库中。用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它。存储过程是 SQL 语句和可选控制流语句的预编译集合,以一个名称存储并作为一个单元处理。存储过程存储在数据库内,可由应用程序通过一个调用执行,而且允许用户声明变量、有条件执行以及其它强大的编程功能。存储过程在创建时即在服务器上进行编译,所以执行起来比单个 SQL 语句快。

存储过程的优点
(1)存储过程只在创造时进行编译,以后每次执行存储过程都不需
再重新编译, 而一般 SQL 语句每执行一次就编译一次,所以使用存储过程可提高数据库执行
速度;
(2) 当对数据库进行复杂操作时(如对多个表进行 Update, Insert, Query, Delete 时) ,
可将此复杂操作用存储过程封装起来与数据库提供的事务处理结合一起使用;
(3)存储过程可以重复使用,可减少数据库开发人员的工作量;
(4)安全性高,可设定只有某此用户才具有对指定存储过程的使用权。

存储过程的缺点
(1)如果更改范围大到需要对输入存储过程的参数进行更改,或者
要更改由其返回的数据,则您仍需要更新程序集中的代码以添加参数、更新 GetValue() 调
用, 等等, 这时候估计比较繁琐了。
(2) 可移植性差。
由于存储过程将应用程序绑定到 SQL Server,因此使用存储过程封装业务逻辑将限制应用程序的可移植性。

存储过程和函数的区别

过程没有返回值 通过参数的in、out和in out 决定是传入参数还是输出参数
函数有返回值 功能没有过程强大

create or replace procedure person_count
as pcount number(4);
begin 
    select count(*) into pcount from tbl_person;
    dbms_output.put_line('the number is :'||pcount);
end;
--调用测试
-- 命令窗口或者sqlplus里面使用  
--execute person_count;
-- sql窗口直接测试  输出结果
begin
  person_count;
end;
--  Java 代码里使用
--  call person_count 

–in out 参数

create or replace procedure p_1(n in out number) is
    r tbl_person%rowtype;
BEGIN
     dbms_output.put_line('pid   pname');
     select * into r from tbl_person where pid = n;
     dbms_output.put_line(r.pid||' '||r.pname);
     dbms_output.put_line('--------');
    n:=r.pid; 
END;
--使用过程:
declare
    n number(11);
begin
    n:=&请输入员工号;
    p_1(n);
    dbms_output.put_line('n is  '||n);
end; 

– in 参数 和 out参数

--create or replace procedure get_person_name(p_id in number(11),p_name in out varchar(20))

–不能在参数里面定义变量的大小 不然创建的过程会有一个×

create or replace procedure get_person_name(p_id in number,p_name in out varchar)
is 
begin
    select pname into p_name from tbl_person where pid = p_id;
    dbms_output.put_line('id is  '||p_id||'  while name is :'||p_name);
end;
--调用过程
declare name varchar(20);id number(11);
begin 
  id:=&请输入员工号;--用户交互输入   输入值之后赋给id
  get_person_name(id,name);
end;
exception
    when no_data_found then
      dbms_output.put_line('no person!');
return null;

3、函数

函数
–参数不能设置变量大小
–但是变量声明时 如下面的m 因为要把tbl_person里pname的值传给m,所以m的类型必须完全与pname相同

create or replace function get_name(n number) return varchar
is m varchar(20);
begin
  select pname into m from tbl_person where pid = n;
  return m;
end;
--调用
declare n number(11);m varchar(20);
begin
  n:=&请输入员工号;
  m:=get_name(n);
  dbms_output.put_line('id is  '||n||'  while name is :'||m);
end;

–函数

create or replace function f_1(n number) return varchar is
    r tbl_person%rowtype;
BEGIN
     dbms_output.put_line('pid    pname');
     select * into r from tbl_person where pid = n;
     dbms_output.put_line(r.pid||' '||r.pname);  
     return r.pid;
END;
--使用函数:
declare
    id number(11);
     name varchar(20);
begin
    id:=&请输入员工号;
    name:=f_1(id);
    dbms_output.put_line('id is '||id||' while name is :'||name);
end;

4、包

包 管理过程和函数的东西 这两个东西都可以放在包里面
–包头: 公共部分 和 包体:私有部分
– 公共部分放过程函数声明
– 包体放过程和函数的具体实现

5、数据库链接

数据库链接 database link
–可以直接 用本地数据库通过 数据库链接 访问远程数据库的 表
–1.需要有create database link 系统权限
–2.登录本地数据库
–3.CREATE DATABASE LINK 链接名 CONNECT TO 账户 IDENTIFIED BY 口令 USING 服务名;
–4.访问远程数据库的表 表名@数据库链接名
– 表名@数据库链接名 相当于在本地数据库中直接使用的表名

6、Job

job 定时任务 可设置定时调用过程或函数或包 实现数据库的定时操作

–创建一个job 实现每3秒钟往下表中插入当前时间

create table time_job(
       id number(11),
       t_date date
)
--创建序列
create sequence time_job_seq  increment by 1 start with 1 maxvalue 999 minvalue 1 nocycle nocache;

--创建过程  实现每次调用过程就在time_jobTest表中插入当前时间
create or replace procedure set_time_job_value as
begin
  insert into time_jobTest values(time_job_seq.nextval,sysdate,'123');
end;
--创建job对象     一旦执行,job对象就开始自动运行向表中插入数据
declare test_job number;--声明一个job对象test_job    
begin
  dbms_job.submit(test_job,'set_time_job_value;',sysdate,'sysdate+3/86400');
  commit;
end;

‘set_time_job_value;’ 注意这里有个分号 千万不能掉
what值是有一个分号的 千万别掉了 掉了会报好几个错 ora 06550 ora 06512 什么’end’值之类的

--删除job对象  用job的ID号删除
select * from user_jobs;
begin
  dbms_job.remove(24);
end;

7、触发器

触发器
select * from time_jobTest;
delete from time_jobTest where 1=1;

select * from tbl_person;

alter table time_jobTest add t_type varchar(20);

select * from time_jobTest;
delete from time_jobtest;

–创建触发器 person_log
–实现每次对表tbl_person增删改记录的时候 在time_jobTest里插入增删改的信息

create or replace trigger person_log 
after
insert or delete or update  on scott.tbl_person 
--加上 of  字段名  表示只针对该字段的操作会触发事件

for each row –表示是行级触发器 不加这句的话默认是语句触发器

 begin 
    if inserting then  --inserting updating deleting 是Oracle 触发器提供的条件谓词
      insert into time_jobTest values(time_job_seq.nextval,sysdate,'insert');
     elsif deleting then -- 注意这里是elsif  不是else if 
      insert into time_jobTest values(time_job_seq.nextval,sysdate,'delete');
     elsif updating then
      insert into time_jobTest values(time_job_seq.nextval,sysdate,'update');
     end if;
   end;         

注意这里是elsif 不是else if

--测试触发器
DELETE from tbl_person WHERE pid = 17;

insert into tbl_person values(tbl_person_seq.nextval,'zhao3','boy','jbkJK');

update tbl_person set pname = 'change_zhao3' where pid = 17;
:new 和 :old 的使用

new — 触发器执行过程中触发表作操作的当前行的新纪录

old — 触发器执行过程中触发表作操作的当前行的旧纪录

**要注意
1、必须是行级触发器。

因为:new或者:old是当前触发表操作的当前行的新数据或者旧数据,所以必须在行级触发器中才能使用。 否则编译时会出现错误。

2、当触发器被不同事件触发时,需要注意:

  • insert触发操作 只 :new
  • delete触发操作 只 :old
  • update触发操作 都行

    如果违反上述操作中随意使用:new或者:old不会在编译时报错误但是会发现使用这两个关键字无效。

3、使用触发器时如果要修改:new的值需要注意:

只行级前触发器才能修改:new的值,而行级后触发器不可以。

因为行级前触发器是在本行DML操作之前,所以才能修改:new的值。从逻辑上说,也只在这时修改才意义。 如果行级后触发器要试图修改:new的值会报变异错误。从逻辑上说后触发器的执行已经在本行DML操作,以后了, 再修改:new的值已经不会对数据产生影响了。

4、当在触发条件中使用:new或者:old的时候注意,只能直接写 old或者new,不能带符号”:”否则会出错。

–触发器种类

–DDL触发器 针对表中的数据操作 insert update delete 这些会有相应的触发事件
–DML触发器 针对表的操作 create drop alter
–数据库触发器 针对数据库的操作 startup shutdown logon logoff severerror

–行级触发器对DML语句影响的每个行执行一次。
–语句级触发器对每个DML语句执行一次,

事件

种 类 关 键 字 含 义
DML事件(3种) INSERT 在表或视图中插入数据时触发
UPDATE 修改表或视图中的数据时触发
DELETE 在删除表或视图中的数据时触发
DDL事件(3种) CREATE 在创建新对象时触发
ALTER 修改数据库或数据库对象时触发
DROP 删除对象时触发
数据库事件(5种) STARTUP 数据打开时触发
SHUTDOWN 在使用NORMAL或IMMEDIATE选项关闭数据库时触发
LOGON 当用户连接到数据库并建立会话时触发
LOGOFF 当一个会话从数据库中断开时触发
SERVERERROR 发生服务器错误时触发

你可能感兴趣的:(oracle)