#1、create table:创建数据库表
#创建表:create table 表明(变量名1 类型,变量名2 类型,变量名3 类型,...);
SQL> create table emp(id number(5));
SQL> create table emp2(id number(5)) tablespace ts1; #指定表空间
#2、create index:创建数据库表的索引
#SQL> create index 索引名 on 表名(列名);
SQL> create index name_index on emp(name)
#3、drop table:删除一个表之后,表及它所包含的所有数据都将删除,这个表所创建的任何索引也将删除
SQL> drop table employee;
#4、drop index:删除数据库索引
#SQL> drop index 索引名 on 表名(列名);
SQL> drop index index_name on emp;
#5、truncate:截断一个表,表中包含的所有行都将被删除,但表本身将会保留
SQL> truncate table emp
#补充:truncate table 在功能上与不带 where 子句的 delete 语句相同:二者均删除表中的全部行。但 truncate table 比 delete 速度快,且使用的系统和事务日志资源少。
#6、alter table:更改表结构,增加、删除列
#1)添加字段:
SQL> alter table emp add(name varchar2(30));
#2)修改字段名:
SQL> alter table emp rename column name to empName;
#3)修改字段类型
SQL> alter table emp modify empName varchar2(100);
#4)删除字段:
SQL> alter table emp drop column empName;
#补充sql常用语句、
#1)重命名表:
SQL> rename emp to employee;
#2)desc 作为降序排序的关键字,desc + 表名:显示表的详细字段
SQL> desc emp;
DML(data manage language,数据操纵语言)
#1、insert:添加数据到数据库中
#insert into 表名(列名1,列名2,...)values(值1,值2,...);
SQL> create table emp(id number(7),name varchar2(30),sex char(1));
SQL> insert into emp values(101,'tom','m');
SQL> insert into emp values(101,'张三',null);#null:空,代表没有值
SQL> insert into emp(id,name)values(201,'jerry');#给指定的字段添加记录值
#2、update:修改数据库中的数据
#update 表名 set 列名1=值1,列名2=值2,...
SQL> update emp set sex='f';
SQL> update emp set sex='m' where name='tom';#where:引导条件过滤
练习:把员工201的,姓名改成李四,性别改成m
SQL> update emp set name='lisi',sex='m' where id=201;
练习:把员工号201或101或301的性别改成f
SQL> update emp set sex='f' where id=201 or id=101 or id=301;#or是或,and是且
#3、delete:删除数据库中的数据
#delete from 表名 emp
SQL> delete from emp;#删库跑路大法
SQL> delete from emp2 where id=201;
DQL(Data Query Language,数据查询语言) — select选择查询语句
普通查询
#select 列名 from 表名
SQL> select * from stu;
SQL> select id,age from stu;
#where条件查询sql
SQL> select name from stu where id=101;
比较运算符:=、>、<、>=、between and、is null、is not null(见名知意)
SQL> select name from stu where id=101;
SQL> select name from stu where id>101;
#orale中数据为空值不参与运算符得比较,查不到结果,所以用is null查询
SQL> select name,id from stu where age is null;
SQL> select name,id from stu where age is not null;
SQL> select * from stu where score between 80 and 90;
逻辑运算:and、or
#查不到score为空的
SQL> select * from stu where score>80 and socre<90;
SQL> select * from users where name='tom' and password='123';
#利用or运算的sql的注入漏洞(黑客中的sql注入)
SQL> select * from users where name='tom' and password='xxx'or '1'='1';
算术运算:+、-、*、/
SQL> select * from stu where id=100+1;
SQL> select score+10*2/4 from stu;
常用关键词
1、in:包含
SQL> select * from stu where id in(101,102,103);
2、like: 模糊查询
% :表示任意个字符,包括零个;
_ :表示一个任意字符
SQL> select * from stu where name like '张%';
SQL> select * from stu where name like '_佳';
3、distinct:过滤重复记录
SQL> select distinct name from stu;
#补充说明:distinct这个关键字来过滤掉多余的重复记录只保留一条,但往往只用 它来返回不重复记录的条数,而不是用它来返回不重记录的所有值。其原因是distinct只有用二重循环查询来解决,而这样对于一个数据量非常大的站来说,无疑是会直接影响到效率的。
4、as:别名
SQL> select name,score as point from stu;
5、order by:排序(默认为升序。空值作为排序时,按无穷大处理。)
#asc:升序,desc:降序
SQL> select * from stu order by id;
SQL> select * from stu order by id asc;
SQL> select * from stu order by id desc;
#含多个排序参数,依次排序,where与order by连用(判断score不是空值后,先按照score降序,再按照id升序)
SQL> select * from stu where score is not null order by score desc,id asc;
分组查询
#分组查询:在带有group by子句的查询语句中,在select 列表中指定的列要么是group by子句中指定的列,要么包含聚合函数,否则就会报错
SQL> select salary from emp group by sex;#报错
SQL> select max(salary)from emp where age>20 group by sex;
SQL> select max(salary),sex from emp group by sex;
#分组后的排序:据男女分组,按分组后的工资排序升序
SQL> select max(salary) as s,sex from emp group by sex order by s;
#group by子句中使用having 子句时,查询结果中只返回满足having条件的组。分组前可以使用where语句,分组后的条件过滤,用having,不能用where
SQL> select addr,avg(salary) from emp where age>20 group by addr having avg(salary)>=6000;
#关于分组的补充:
1、分组函数(聚合函数): max() min() avg() sum() count()
2、having与where子句类似,均用于设置限定条件。其区别如下:
1)where子句的作用是在对查询结果进行分组前,将不符合where条件的行去掉,即在分组之前过滤数据,条件中不能包含聚合函数,使用where条件显示特定的行。
2)having子句的作用是筛选满足条件的组,即在分组之后过滤数据,条件中经常包含聚合函数,使用having条件显示特定的组,也可以使用多个分组标准进行分组。
嵌套查询(子查询)
1、行子查询(子查询的结果作为值)子查询不能包括ORDER BY子句
SQL> select name,age from emp where salary=(select max(salary) from emp);
2、行子查询
SQL> select name,age from emp where salary in(select min(salary) from emp group by addr);
3、表子查询(子查询的结果作为临时表)
SQL> select * from(select name,age,salary from emp);
分页查询
#隐藏列:rownum(只能进行<运算) emp.*是该表全部列
SQL> select rownum,emp.* from emp where rownum <3;
#分页思想:使用临时表和列的别名,把隐藏列转换为普通的列 rn
SQL> select tempTable.* from (select rownum as rn,emp.* from emp) tempTable where rn>=3 and rn<=4;
分页算法:
每页显示条数:pageSize
要显示的页数:pageNum
rn>=(pageNum-1)*pageSize+1 and rn<=pageNum*pageSize
eg:p每页显示5条,显示第3页 ---> rn>=(3-1)*5+1 and rn<=5*3
有排序的分页算法:
#eg:按id排序,分页查询,每页3条记录,查询第2页
SQL> select tempTable.* from (select rownum as rn,emp.* from emp order by id asc) tempTable where rn between (2-1)*3+1 and 2*3;
多表查询
1、交叉连接:表与表之间做笛卡尔积查询!根据笛卡尔积进行完全链接,会有垃圾数据
SQL> select * from emp cross join dept;
SQL> select * from emp,dept;
2、内连接(inner可以省略):
SQL> select * from emp inner join dept on emp.deptno=dept.deptno;
3、外连接
1)左外链接(左边的表是主表):查询结果除了返回包含连接条件的行,还包含左表a中不满足连接条件的行,其中不满足连接条件的行中b表的字段值将被置为空
#left outer join ... on
SQL> select * from emp left outer join dept on emp.deptno=dept.deptno;
2)右外链接(右边的表是主表):与左外连接相反
#right outer join ... on
SQL> select * from emp right outer join dept on emp.deptno=dept.deptno;
3)全连接:左右两表都会有数据
#full outer join ... on
SQL> select * from emp full outer join dept on emp.deptno=dept.deptno;
4、自然连接:使用自连接可以将自身表的一个镜像当作另一个表来对待,从而能够得到一些特殊的数据。自连接的本意就是将一张表看成多张表来做连接
#例:查询出学生和其所在班级的班长的一个
SQL> SELECT t1.s_id, t1.s_name,t2.s_id,t2.s_name FROM t_student t1 INNER JOIN t_student t2 ON t1.s_pid = t2.s_id;
合并查询:
1、union all:使用UNION ALL,表示取A、B的合集,不过滤重复的数据行
SQL> select name from emp union all select addr from dept;
2、union:取查询结果的并集(同时会过滤掉同一个表中的重复字段)会将结果集A和结果集B进行union all运算,然后取两者交集的余集作为结果集
SQL> select name from emp union select addr from dept;
3、intersect将结果集A和结果集B进行union all运算,然后两者之间的集交集作为结果集
SQL> select name from emp intersect select addr from dept;
4、minus:取结果集A减去结果集B留下的差集,注:如果结果集A小于等于结果集B,返回空结果集.
SQL> select name from emp minus select addr from dept;
如果你看不懂,请看下方合并查询的图解
TCL(Transaction Control Language,事务控制语言) 1、commit:用于提交前面所做的所有操作。
有一些操作需要手动添加commit才能够将修改提交给库,而有一些操作只需要执行系统会自动commit。
2、rollback:撤销在上一次执行COMMIT命令之后执行的所有DML操作。
3、savepoint:设置回滚点
一组DML操作指令,正常完成时一起进行提交,出现异常时一起回退
DCL(Data Control Language,数据控制语言) — grant、revoke、lock
常用命令
#切换连接用户指令:
SQL> conn sys;
#查看用户:
SQL> show user;
#断开用户连接:
SQL> disconn system;
#退出:
SQL> quit;
#查看当前数据库(系统)的数据库名(实例)
SQL> select name from v$database;
#查看当前数据库下有用户
SQL> select * from dba_users;
#创建新用户(最基本规则:1.一般都是字母开头2.不能有空格):
SQL> create user zhangsan identified by abc;
#更改用户密码:
SQL> alter user system identified by 123456;
grant(授予权限)
#授予zhangsan用户创建session的权限,即登陆权限,允许用户登录数据库
SQL> grant create session to zhangsan;
#授予zhangsan用户使用表空间的权限
SQL> grant unlimited tablespace to zhangsan;
#授予创建表的权限
SQL> grant create table to zhangsan;
#授予删除表的权限
SQL> grant drop table to zhangsan;
#授插入表的权限
SQL> grant insert table to zhangsan;
#授予修改表的权限
SQL> grant update table to zhangsan;
#授予所有权限(all)给所有用户(public)
SQL> grant all to public;
revoke(撤销已授予的权限)
#撤销zhangsan用户创建session的权限,即登陆权限,允许用户登录数据库
SQL> revoke create session from zhangsan;
#撤销zhangsan用户使用表空间的权限
SQL> revoke unlimited tablespace from zhangsan;
#撤销创建表的权限
SQL> revoke create table from zhangsan;
#撤销删除表的权限
SQL> revoke drop table from zhangsan;
#撤销插入表的权限
SQL> revoke insert table from zhangsan;
#撤销修改表的权限
SQL> revoke update table from zhangsan;
#撤销所有权限(all)给所有用户(public)
SQL> revoke all from public;
lock(锁)
#用户锁定:
SQL> alter user zhangsan account lock;
#用户解锁:
SQL> alter user zhangsan account unlock;
#共享锁:有共享锁的事务只能读数据,不能修改数据。
如果事务T对数据A加上共享锁后,则其他事务只能对A再加共享锁,不能加排他锁。
注:共享锁是表级的
#排他锁:有排他锁的事务既能读数据,又能修改数据。
如果事务T对数据A加上排他锁后,则其他事务不能再对A加任任何类型的锁。
注:排他锁一般是行级的
#select...for update命令在将要更改的记录上放置了一个共享锁,防止其他任何用户获得同样记录上的锁。
SQL> select * from emp where id=101 for update;
1、标准索引
#查看当前用户下的索引
SQL> select * from user_indexes;
#创建索引(根据某个表的某个列)
SQL> create index a_index on emp(id);
#重建索引
SQL> alter index a_index rebuild;
#删除索引
SQL> drop index a_index;
2、唯一索引:唯一索引确保在定义索引的列中没有重复值,Oracle 自动在表的主键列上创建唯一索引
#使用CREATE UNIQUE INDEX语句创建唯一索引
SQL> CREATE UNIQUE INDEX x_id ON itemfile (f_id);
3、组合索引:在表的多个列上创建的索引,索引中列的顺序是任意的
#如果 SQL 语句的 WHERE 子句中引用了组合索引的所有列或大多数列,则可以提高检索速度
SQL> CREATE INDEX x_comp ON t_student(f_name, f_birth);
4、反向键索引
5、位图索引
6、基于函数的索引
1.限制:(可以使用 check 约束替代,用 is null作为条件。)
1)不能在视图中使用
2)不能在数据库对象的属性中使用。
2.操作:
#创建非空约束
SQL> create table stu01(id number(5) not null);
#此时STU01作为记录值,必须大写
SQL> select * from user_constraints where TABLE_NAME='STU01';
#自定义约束名
SQL> create table stu03(id number(5)not null, name varchar2(30)constraint name_con not null);
#修改非空约束
SQL> alter table stu03 modify name null;
SQL> alter table stu03 modify name not null;#此时要确保表中name列 没有null的
唯一性约束:unique
#创建唯一性约束
SQL> create table stu04(id number(5) unique, name varchar2(30) unique);
#修改唯一性约束
SQL> alter table stu04 drop unique(name);
SQL> alter table stu04 add unique(name);
null不参与唯一性比较
块语法结构 declare
声明语句...
begin
执行语句...
exception
异常处理语句...
end;
语法解析:
1、声明部分是可选部分,由declare开始,声明执行部分所需的变量或者常量。假如,没有用到变量或者常量可以省略。
2、执行部分是由begin开始,end结束。是PL/SQL块语句的核心部分,所有的可执行的PL/SQL语句和操作变量都放在该部分。是必选的部分,不能省略。
3、异常部分是由exception开始。主要处理执行部分过程中的执行语句或者赋值操作出现错误时,就会进入该部分。是PL/SQL程序的异常处理部分,不是必须的。
eg:输出学生信表中的某一位学生的基本信
declare
-- 声明变量
stuinfo varchar2(50);
begin
select '姓名:' || stuname || ' 学号:' || stuid || ' 年龄:' || age into stuinfo from stu
where t.stuname = '张三';
dbms_output.put_line(stuinfo);
exception
when no_data_found then
dbms_output.put_line('该学生在学生信表中找不到');
end;
解释:
1、|| 是字符串连接运算 -- 是注释
2、select ... into是PL/SQL程序中对SQL查询语句给变量赋值方法。是PL/SQL程序特有的赋值语句,该赋值语句只能要求SQL语句查询出来的值只有一个,假如多个或者一个都没有回抛出异常。
3、dbms_output.put_line是Oracle系统自带的包中的过程,用来做输出流打印,经常可以用来开发PL/SQL程序时做测试用。
4、no_data_found:如果没有找到查询结果则触发
数据类型
标量数据类型
1、数值类型: number(size),pls_integer,binary_integer和simple_integer
2、字符类型: char(size),varchar2(size),long
3、时间类型: date
4、布尔类型: true,false,null
引用数据类型
1、自适应列类型:%type(引用数据库中表的某列的类型作为某变量的数据类型,也可以直接引用PL/SQL程序中某个变量作为新变量的数据类型。)
eg:
declare
ls_stuname stu.name%type; -- 通过学生姓名字段声明ls_stuname
begin
select stu.name into ls_stuname from stu where stu.stuid = '101';
dbms_output.put_line(ls_stuname);
exception
when no_data_found then
dbms_output.put_line('该学生在学生信表中找不到');
end;
2、自适应行类型:%rowtype(PL/SQL程序引用数据库表中的一行作为数据类型,即 record 类型(记录类型)表示一条数据记录。)
eg:
declare
ls_stuinfo stu%rowtype;
stuinfo varchar2(50);
begin
select * into ls_stuinfo from stu where id='101';
-- := 赋值运算符
stuinfo:='姓名:' ||ls_stuinfo.stuname || ' 学号:' ||ls_stuinfo.stuid || '年龄:' || ls_stuinfo.age;
dbms_output.put_line(stuinfo);
exception
when no_data_found then
dbms_output.put_line('该学生在学生信表中找不到');
end;
补充:运算符
1、比较运算符 =
2、赋值运算符 :=
3、字符串连接运算符 ||
流程控制
顺序结构
顺序结构我们经常使用到GOTO的关键字进行程序的跳转,goto 不能跳转到 if 语句、 case 语句、 loop 语句、或者子块中,因此,不在非不得已的情况下,不使用GOTO语句。
总结:花里胡哨没啥用!
eg:
declare
ls_stuinfo stuinfo%rowtype;
msg varchar2(50);
begin
select t.* into ls_stuinfo from stuinfo t where t.stuid='SC201801006';
msg:='姓名:' ||ls_stuinfo.stuname || ' 学号:' ||ls_stuinfo.stuid || ' 年龄:' ||ls_stuinfo.age;
dbms_output.put_line(msg);
if ls_stuinfo.age>25 then
goto flag1;
else
goto flag2;
end if;
<<flag1>>
dbms_output.put_line(msg||' 年龄大于25岁');
<< flag2>>
null;
exception
when no_data_found then
dbms_output.put_line('该学生在学生信表中找不到');
end;
解释说明:
1、其中通过判断学生“张三丰”的年龄是否大于25岁,大于就跳转到flag1标志位开始继续顺序执行程序。
2、NULL在PL/SQL程序中是顺序结构当中的一种,表示不执行任何内容,直接跳过,因此,当年龄小于等于25岁,该学生年龄大于25岁的信将不会被打印出来。
条件控制
if 条件1 then
-- 条件1成立执行体;
elsif 条件2 then
-- 条件1不成立,条件2成立执行体;
else
-- 条件都不成立执行体;
end if;
-- eg:判断变量num_in范围
declare
num_in number(5)
begin
num_in:=20
if num_in<5
then dbms_output.put_line('输入的值'||num_in||'小于5');
elsif num_in>=5 and num_in<10
then dbms_output.put_line('输入的值'||num_in||'大于等于5,小于10');
else dbms_output.put_line('输入的值'||num_in||'大于等于10');
end if;
end;
case 选择体
when 表达式1 then 执行体;
when 表达式2 then 执行体;
when 表达式3 then 执行体;
...
else 表达式n then 执行体;
end case;
#eg:与上面类似,懒得举例了
循环结构
-- 通过循环体直接进行loop循环
for 循环体别名 in (SELECT 条件查询数据) loop
-- 循环执行体;
end loop;
# 通过选择体case when区分出学生信表中学生的各个年龄的人数
declare
ls_stuinfo stuinfo%rowtype;-- 学生信表
ls_number_26 number:=0;-- 26岁计数器
ls_number_27 number:=0;-- 27岁计数器
ls_number number:=0;-- 其它
begin
-- 对学生信表进行全表循环
for ls_stuinfo in ( select t.* from stuinfo t ) loop
case ls_stuinfo.age
when 26 then
ls_number_26:=ls_number_26+1;
when 27 then
ls_number_27:=ls_number_27+1;
else
ls_number:= ls_number+1;
end case;
end loop;
dbms_output.put_line('26岁:'||ls_number_26||'人,27岁:'||ls_number_27||'人,其它岁数:'||ls_number||'人');
end;
-- 通过循环变量进行循环
for 循环变量 in 循环下限...循环上限 loop
end loop;
#eg:
declare
type stuinfo_type is table of stuinfo%rowtype;-- 学生信表
ls_stuinfo stuinfo_type;-- 声明一个集合变量(学生集合变量)
ls_number number:=0;-- 计数器
begin
-- 赋值给学生集合变量
select * BULK COLLECT into ls_stuinfo from stuinfo;
-- 对集合变量进行for循环,通过下标取值
for i in 1.. ls_stuinfo.count loop
if ls_stuinfo(i).sex='1' then--性别编码为1的是男生
ls_number:=ls_number+1;--计数器加1
end if;
end loop;
dbms_output.put_line('男生的数量是:'||ls_number);
end;
-- while循环
while 条件 loop
-- 循环执行体
end loop;
#eg:一个简单1加到n(n=4)的代码的while循环代码
declare
ls_number number:=0;--结果值
i number:=1;--计数器
begin
while i<=4 loop
ls_number:=ls_number+i;
i:=i+1;
end loop;
dbms_output.put_line(ls_number);
end;
1、创建函数
create [or replace] function 函数名 ([p1,p2...pn])
return datatype
is|as
-- 声明部分
begin
-- PL/SQL程序块
end
语法解析:
1、function 是创建函数的关键字。
2、p1,p2...pn是函数的入参,Oracle创建的函数也可以不需要入参。
3、return datatype:是函数的返回值的类型
4、通过is承接着PL/SQL程序块。这部分是函数的计算内容。
#eg:
create or replace function a_fun
return varchar2
is
name_out varchar2(30);
begin
select name into name_out from emp where name='mary'; return name_out;
end;
使用: SQL> select a_fun from dual
2、修改函数:通过 or replace 关键词对原有的函数进行编辑覆盖
3、删除函数:通过drop命令进行删除的
drop function 函数名;
1、声明游标:
#声明游标是给游标命名并给游标关联一个查询结果集,具体声明语法如下:
declare cursor cursor_name(游标名)
is select_statement(查询语句);
2、打开游标:
#游标声明完,可以通过打开游标打开命令,初始化游标指针,游标一旦打开后,游标对应的结果集就是静态不会再变了,不管查询的表的基础数据发生了变化。打开游标的命令如下:
open cursor_name;
3、读取游标中数据:
#读取游标中的数据是通过fetch into语句完成,把当前游标指针指向的数据行读取到对应的变量中(record 变量)。游标读取一般和循环LOOP一起使用,用于循环获取数据集中的记录。
fetch cursor_name into record变量
4、关闭游标:
#游标使用完,一定要关闭游标释放资源。关闭后,该游标关联的结果集就释放了,不能够再操作了,命令如下:
close cursor_name;
常用属性:
1、%notfound。表示游标获取数据的时候是否有数据提取出来,没有数据返回TRUE,有数据返回false。经常用来判断游标是否全部循环完毕
2、%found。正好和%notfound,当游标提取数据值时有值,返回TRUE,否则返回FALSE。
3、%isopen。用来判断游标是否打开。
4、%rowcount。表示当前游标fetch into获取了多少行的记录值,用来做计数用的。
#eg1:创建一个游标循环打印学生信表中学生基本信
declare
-- 定义游标
cursor cur_msg is
select * from stuinfo order by stuid;
-- 定义记录变量
ls_curinfo cur_msg%rowtype;
begin
open cur_msg;-- 打开游标
loop
fetch cur_msg into ls_curinfo;-- 获取记录值
exit when cur_msg%notfound;
dbms_output.put_line('学号:' || ls_curinfo.stuid || ',姓名:' ||ls_curinfo.name);
end loop;
close cur_msg;-- 关闭游标
end;
代码解析:
通常我们使用显式游标都是用来循环取数据集的,因此会经常如eg1一样,使用loop控制结果来搭配使用,通过游标的属性变量%notfound来获取游标的结束,跳出loop循环。
#eg2:我们经常用到%rowcount作为游标的计数器,我们修改一下eg1的代码,用上%rowcount
declare
-- 定义游标
cursor cur_msg is
select * from stuinfo order by stuid;
-- 定义记录变量
ls_curinfo cur_msg%rowtype;
begin
open cur_msg;-- 打开游标
loop
fetch cur_msg into ls_curinfo;--获取记录值
exit when cur_msg%notfound;
-- 利用游标计数器打印学生个数
dbms_output.put('%rowcount计数器,第'||cur_msg%rowcount||'位学生,');
dbms_output.put_line('学号:' || ls_curinfo.stuid || ',姓名:' ||ls_curinfo.name);
end loop;
close cur_msg;-- 关闭游标
end;
隐式游标:
概念
隐式游标指的是PL/SQL自己管理的游标,开发者不能自己控制操作,只能获得它的属性信。
使用
eg3:
declare
ls_msg stuinfo%rowtype;
begin
-- 查询学生信
select * into ls_msg from stuinfo t where t.stuid = 'SC201801001';
if sql%found then
dbms_output.put_line('学号:' || ls_msg.stuid || ',姓名:' ||ls_msg.stuname);
end if;
-- 查询学生信(不存在的学生)
select * into ls_msg from stuinfo t where t.stuid = 'SC201901001';
if sql%found then
dbms_output.put_line('学号:' || ls_msg.stuid || ',姓名:' ||ls_msg.stuname);
end if;
exception
when no_data_found then
dbms_output.put_line('该学生SC201901001不存在');
end;
代码解析:
oracle隐式游标没有像显式游标一样声明游标名,直接采用SQL名称作为隐式游标的名称。然后可以利用游标的属性,做一些逻辑判断,隐式游标的属性值和显式的一样,有%notfound、%found、%rowcount、%isopen。显式游标表示的属性值都是对结果集行数的一些判断,而隐式游标对应的就是DML语句影响的行数
类型(按照用户具体的操作事件的类型) 1、数据操作(DML)触发器
2、数据定义操作(DDL)触发器
3、用户和系统事件触发器
4、instead of 触发器
5、复合触发器
操作方法: eg:创建一个简单的触发器来校验学生基本信的正确性
create or replace trigger tr_msg_insert
before insert on stuinfo
for each row
begin
-- 对性别的数据进行校验
if :new.sex not in ('m', 'f') then
raise_application_error(-20001, '性别错误,请正确选择。');
end if;
end;
#:new --为一个引用最新的列值;
#:old --为一个引用以前的列值;
#这两个变量只有在使用了关键字 "for each row"时才存在.且update语句两个都有,而insert只有:new ,delect 只有:old;
代码解析:这是一个DML触发器,是对学生信表(stuinfo)学生数据插入(insert)之前做的一个性别的校验,当性别的值不符合规范的时候报数据错误。
禁用/启用触发器:
SQL> alter trigger a_trig disable;
SQL> alter trigger a_trig enable;
删除触发器:
SQL> drop trigger a_trig;
创建包 create or replace procedure b_pro(name_in varchar2)
is
name_out varchar2(30);
begin
select name into name_out from emp where name=name_in;
dbms_output.put_line(name_out);
end;
- ##### 创建包体
```sql
create or replace package body a_pack
is
procedure temp_pro(name_in varchar2) #定义一个过程
is
name_out varchar2(30);
begin
select name into name_out from emp where name=name_in;
dbms_output.put_line(name_out);
end;
function temp_fun return varchar2 #定义一个函数
is
name_out varchar2(30);
begin
select name into name_out from emp where name='mary';
return name_out;
end;
end;
执行
#执行包中的函数或过程
SQL> select a_pack.temp_fun from dual;
SQL> exec a_pack.temp_pro('mary');