oracle安装学习总结
oracle安装
1.解压好之后。点击exe
等它检检测好会弹出下面的窗口
2.第一个不选
3.选第一个
4.
5.
因为我已经安装过了,所以选的要少
第一装的顺序是:
1.不选 2.选1 3.服务 4. 1 5.2 6.随便 7.1 8.数据库名称 9.软件运行
上面选好后它会进入先决条件检测 40% and 80%的地方容易卡 如果卡了很久没有动。恭喜你 你要重装系统了
检测好后会再弹一个窗口 等这个窗口运行完 进入 口令管理 scott 不能锁 所以不勾选
最后安装好后 点电脑的菜单栏 会有oracle的文件夹 打开点击里面的最后一个文件夹应用程序开发 点开SQLPLUS
输入scott 密码是tiger
第一次输入会提示是否要修改密码 可改可不改 最后输入查询语句 select * from emp;测试即可
解压文件 点击安装 plsql
安装好桌面有个这个图标
点击
输入scott 密码123456
点击file---》new ---》sql windows
就会出现如上窗口 输入sql 点击下图位置即可运行
如果要卸载oracle 先将服务下的八个文件停止运行 然后安装路径下的文件删除,然后去 c盘将虾下面两个文件夹里的oracle文件删除 环境变量中去掉oracle 最后输入 田键+r键 在窗口输入regedit 删除Windows的配置文件
将划线文件夹下的oracle文件删除
将这个两个的service下的oracle文件删除 最后检查一遍即可重新安装
select除了可以做查询 还可以做运算
select 1+2
varchar 可变长度字符串
char 固定长度字符串
Date DateTime --->int 可转为毫秒数 用int存贮
text :可存html
blob: binary large object word。。。二进制的大数据
约束:保证数据的合法性
unique 唯一约束
primary key 主键约束
not null 非空约束
default 默认约束
foregin key 外键约束
check
char(10) :这个10表示字节数,字符数。默认为字节,最大 2000
在MYSQL里面''与“”一样
如果要使用字符 在创建表时设置 char (10 char)即可
当我们不设置char 插入10个汉字会报错,插入的10个汉字 其实为20个字节 默认的只有10个字节
varchar2 :oracle推荐使用 也有varchar varchar 2比varchar性能要好默认也是字节为单位
nvarchar2:指定了Unicode字符集 其余与varchar2一致
number:所有的自然数 NUMBER(p,s)
number(6,-1);
有效位:从左边第一个不为0的数算起的位数。
s的情况:
s > 0
精确到小数点右边s位,并四舍五入。然后检验有效位是否 <= p。
s < 0
精确到小数点左边s位,并四舍五入。然后检验有效位是否 <= p + |s|。
s = 0
此时NUMBER表示整数。
eg:
Actual Data Specified As Stored As
----------------------------------------
123.89 NUMBER 123.89
123.89 NUMBER(3) 124
123.89 NUMBER(6,2) 123.89
123.89 NUMBER(6,1) 123.9
123.89 NUMBER(4,2) exceeds precision (有效位为5, 5 > 4)
123.89 NUMBER(6,-2) 100
.01234 NUMBER(4,5) .01234 (有效位为4)
.00012 NUMBER(4,5) .00012
.000127 NUMBER(4,5) .00013
.0000012 NUMBER(2,7) .0000012
.00000123 NUMBER(2,7) .0000012
1.2e-4 NUMBER(2,5) 0.00012
1.2e-5 NUMBER(2,5) 0.00001
123.2564 NUMBER 123.2564
1234.9876 NUMBER(6,2) 1234.99
12345.12345 NUMBER(6,2) Error (有效位为5+2 > 6)
1234.9876 NUMBER(6) 1235 (s没有表示s=0)
12345.345 NUMBER(5,-2) 12300
1234567 NUMBER(5,-2) 1234600
12345678 NUMBER(5,-2) Error (有效位为8 > 7)
123456789 NUMBER(5,-4) 123460000
1234567890 NUMBER(5,-4) Error (有效位为10 > 9)
12345.58 NUMBER(*, 1) 12345.6
0.1 NUMBER(4,5) Error (0.10000, 有效位为5 > 4)
0.01234567 NUMBER(4,5) 0.01235
0.09999 NUMBER(4,5) 0.09999
CREATE TABLE stuInfo
(stuNo CHAR(6) NOT NULL, --学号,非空(必填)
stuName VARCHAR2(20) NOT NULL,--学员姓名,非空(必填)
stuAge NUMBER(3,0) NOT NULL,--年龄,非空(必填)
stuID NUMERIC(18,0),--身份证号,NUMERIC (18,0)代表18位数字,小数位为0
stuSeat NUMERIC(2,0)--座位号
);
insert into stuInfo values('1','詹三',18,123456789123456789,25);
insert into stuInfo values('2','abx',16,123456789123456789.97,25.62);
insert into stuInfo values('3','ss',16,123456789123456789,25,'男');
select * from stuInfo;
--添加主键约束 主键为stuNo
alter table stuInfo add constraint stu_info primary key(stuNo);
--删除主键
alter table stuInfo drop constraint stu_info;
--添加唯一约束
alter table stuInfo add constraint stu_only unique(stuNo);
--删除约束
alter table stuInfo drop constraint stu_only;
--增加列
alter table stuInfo add
(
stuSex CHAR(2)
);
--复制两张表,只复制数据 不复制表结构
create table tests as select * from stuInfo;
select * from tests;
--外键约束 stuinfo 为主键 tests 为外键
alter table tests add constraint fk_emp foreign key(stuNo) references stuInfo(stuNo);
alter table stuInfo add constraint sex check (stuSex in('男','女'));
alter table stuInfo add constraint stuAge check (stuAge >= 18 and stuAge <= 30);
运算符:按优先级排列
算术运算符:+ - * / ++ -- oracle 没有 ++ --
比较运算符:> < >= <= == !=
逻辑运算符: ! && || (扩展短路表达式 ,按位与)
赋值运算符:=
短路表达式
* var a=1,b=1,c=2;
* a==b&&c; //2
* a==0&&c; //false
*
* a==b||c; //true
* a==0||c; //2;
x&&y :
首先在运算符比之前会自动把x转换为boolean值,不管它是什么类型。
若x为false,不管y为什么,都将返回false;
若x为true,则返回y,若y可以是基本类型,也可以是引用类型,也可以是一串表达式;
x||y :
同理先把x转换成boolean值。
与&&正好相反,若x为true,不管y为什么,都将返回true;
若x为false,则返回y;
整数在计算机中用二进制的位来表示,C语言提供一些运算符可以直接操作整数中的位,称为位运算,这些运算符的操作数都必须是整型的。
& 按位与, | 按位或 , ^ 按位异或
AND (位与&) OR ( 位或| ) XOR ( 位异或^ )
1 & 1 = 1, 1 | 1 = 1, 1 ^ 1 = 0
1 & 0 = 0, 1 | 0 = 1, 1 ^ 0 = 1
0 & 1 = 0, 0 | 1 = 1, 0 ^ 1 = 1
0 & 0 = 0, 0 | 0 = 0, 0 ^ 0 = 0
exist
between min and max 闭区间 两个都包括
in
like
_
%
lucene Elestic Search 全文搜索技术
集合运算符:
union union all:两个结果集相加(union会排出重复的数据 union all 名称可不一致,列要一致,不一定是同一张表)
minus:两个结果集想减
把竖表变横表 横表变竖表
create table student
(
sName varchar(20) not null,
语文 int,
数学 int,
英语 int
);
select * from student;
insert into student values('张三',78,79,70);
insert into student values('李四',89,88,85);
insert into student values('王五',90,92,97);
create table stu
(
sName varchar(20) not null,
sSub varchar(5),
sCore int
);
select * from stu;--竖表
select * from student;--横表
insert into stu values('张三','语文',78);
insert into stu values('张三','数学',79);
insert into stu values('张三','英语',70);
insert into stu values('李四','语文',89);
insert into stu values('李四','数学',88);
insert into stu values('李四','英语',85);
insert into stu values('王五','语文',90);
insert into stu values('王五','数学',92);
insert into stu values('王五','英语',97);
--竖表变横表
select t1.sname,t1.语文,t2.数学,t3.英语 from
(
select sName,sCore as 语文 from stu where SSUB ='语文'
) t1
left join
(
select sName,sCore as 数学 from stu where SSUB ='数学'
)
t2
on t1.sName=t2.sName
left join
(select sName,sCore as 英语 from stu where SSUB ='英语' ) t3
on t2.sName=t3.sName;
--横变竖
select sName,语文 as object from student
union
select sName,数学 as object from student
union
select sName,英语 as object from student;
||代表字符串拼接 oracle
concat 也是拼接
select concat(concat('aa','bb'),'cc') from dual
select 'aa'||'bb'||'cc' from dual
转义字符 \n 回车 \r oracle表示字符串用 ' '
SELECT '''aaa''' from dual;
--第一个‘表示字符串开始 最后一个表示结束 第二个表示转义后面的’
函数initcap:
假设c为一字符串.函数INITCAP()是将每个单词的第一个字母大写,其它字母变为小写返回.
单词由空格,控制字符,标点符号等非字母符号限制.
select initcap('hello world') from dual;
结果
INITCAP('HELLO WORLD')-----------Hello World
Lpad()函数的用法:
lpad函数将左边的字符串填充一些特定的字符其语法格式如下:
lpad(string,n,[pad_string])
string:可是字符或者参数
n:字符的长度,是返回的字符串的数量,如果这个数量比原字符串的长度要短,lpad函数将会把字符串截取成从左到右的n个字符;
pad_string:是个可选参数,这个字符串是要粘贴到string的左边,如果这个参数未写,lpad函数将会在string的左边粘贴空格。
例如:
lpad('tech', 7); 将返回' tech'
lpad('tech', 2); 将返回'te'
lpad('tech', 8, '0'); 将返回'0000tech'
lpad('tech on the net', 15, 'z'); 将返回'tech on the net'
lpad('tech on the net', 16, 'z'); 将返回'ztech on the net'
—————————————————————————————————————————————————————————
Rpad()函数的用法:
rpad函数将右边的字符串填充一些特定的字符其语法格式如下:
rpad(string,n,[pad_string])
string:可是字符或者参数
n:字符的长度,是返回的字符串的数量,如果这个数量比原字符串的长度要短,lpad函数将会把字符串截取成从左到右的n个字符;
pad_string:是个可选参数,这个字符串是要粘贴到string的右边,如果这个参数未写,lpad函数将会在string的右边粘贴空格。
例如:
rpad('tech', 7); 将返回' tech'
rpad('tech', 2); 将返回'te'
rpad('tech', 8, '0'); 将返回'tech0000'
rpad('tech on the net', 15, 'z'); 将返回'tech on the net'
rpad('tech on the net', 16, 'z'); 将返回'tech on the netz'
oracle中trim,ltrim,rtrim函数用法
oracle中trim,ltrim,rtrim函数用法
该函数共有两种作用:
第一种,即大家都比较熟悉的去除空格。
例子:
--TRIM去除指定字符的前后空格
SQL> SELECT TRIM(' dd df ') FROM dual;
TRIM('DDDF')
------------
dd df
--LTRIM去除指定字符的前面空格
SQL> SELECT LTRIM(' dd df ') FROM dual;
LTRIM('DDDF')
-------------
dd df
--RTRIM去除指定字符后面后空格
SQL> SELECT RTRIM(' dd df ') FROM dual;
RTRIM('DDDF')
-------------
dd df
第二种,去除指定的字符。trim只能去除单个字符,而ltrim和rtrim可以去除多个字符。
trim去除字符的写法:
--表示字符串string2去除前面|后面|前后面(leading|trailing|both)的字符string1,默认去除方式为both
SELECT TRIM(leading|trailing|both string1 FROM string2) FROM dual;
例子:
SQL> SELECT trim(leading 'd' from 'dfssa') FROM dual;
TRIM(LEADING'D'FROM'DFSSA')
---------------------------
fssa
SQL> SELECT trim(both '1' from '123sfd111') FROM dual;
TRIM(BOTH'1'FROM'123SFD111')
----------------------------
23sfd
SQL> SELECT trim(trailing '2' from '213dsq12') FROM dual;
TRIM(TRAILING'2'FROM'213DSQ12'
------------------------------
213dsq1
注:trim去除字符只能是单个字符,如下,要去除的字符若为字符集则报错
SQL> SELECT trim(trailing '12' from '123dsq12') FROM dual;
SELECT trim(trailing '12' from '123dsq12') FROM dual
ORA-30001: 截取集仅能有一个字符
ltrim和rtrim去除字符的写法:
--表示字符串string1去除前面与string2字符集匹配的,若无匹配则结束返回
SELECT ltrim(string1,string2) FROM dual;
--rtrim与ltrim类似,只是去除的是右边算起匹配的字符
SELECT rtrim(string1,string2) FROM dual;
例子:
--如下,由于从右边算起,第一个字母是b没有与'main'匹配的字符,因此返回结果仍是'aaaaminb'
SQL> SELECT rtrim('aaaaminb','main') FROM dual;
RTRIM('AAAAMINB','MAIN')
------------------------
aaaaminb
--如下返回结果为空
SQL> SELECT rtrim('aaaaminb','mainb') FROM dual;
RTRIM('AAAAMINB','MAINB')
-------------------------
SQL> SELECT ltrim('ccbcminb','cb') FROM dual;
LTRIM('CCBCMINB','CB')
----------------------
minb
Oracle的CLOB大数据字段类型
ORACLE时间函数(SYSDATE)深入理解
加法
select sysdate,add_months(sysdate,12) from dual; --加1年
select sysdate,add_months(sysdate,1) from dual; --加1月
--获取当前时间与日期
select sysdate from dual;
--获取本月最后一天
select last_day(sysdate) from dual;
--获取今天是今年的第几天
select to_char(sysdate,'ddd') from dual;
---取得当前日期是本月的第几周
select to_char(sysdate,'YYYYMMDD W HH24:MI:SS')from dual;
//oracle中extract()函数从oracle 9i中引入,用于从一个date或者interval类型中截取到特定的部分
//语法如下:
EXTRACT (
{ YEAR | MONTH | DAY | HOUR | MINUTE | SECOND }
| { TIMEZONE_HOUR | TIMEZONE_MINUTE }
| { TIMEZONE_REGION | TIMEZONE_ABBR }
FROM { date_value | interval_value } )
//我们只可以从一个date类型中截取 year,month,day(date日期的格式为yyyy-mm-dd);
//我们只可以从一个 timestamp with time zone 的数据类型中截取TIMEZONE_HOUR和TIMEZONE_MINUTE;
select extract(year from date'2011-05-17') year from dual;
YEAR
----------
2011
select extract(month from date'2011-05-17') month from dual;
MONTH
----------
5
|
--会锁表
select * from tests for update;
select decode (sex,1,'男',2,'女') from test;--此处会找1将其替换成男
Oracle的NVL函数用法
从两个表达式返回一个非 null 值。
语法
NVL(eExpression1, eExpression2)
参数
eExpression1, eExpression2
如果 eExpression1 的计算结果为 null 值,则 NVL( ) 返回 eExpression2。如果 eExpression1 的计算结果不是 null 值,则返回 eExpression1。eExpression1 和 eExpression2 可以是任意一种数据类型。如果 eExpression1 与 eExpression2 的结果皆为 null 值,则 NVL( ) 返回 .NULL.。
PLSQL: SQL的升级版,是存储化语言sql,多个sql语句的集合。支持变量,常量,触发器,子程序,包,输入输出,处理错误机制。。。
值执行除了sql之外的语言,sql还是需要底层的sql执行
程序:顺序 分支(选择) 循环
[declare]
变量声明;
变量声明;
begin
DML/TCL操作;
DML/TCL操作;
[exception]
例外处理;
例外处理;
end;
declare
i int ;
begin
i:=1;
dbms_output.put_line(i);--输出语句
end;
值得注意的是:eslif并没有写错的,它是少了一个e的
declare
pday varchar2(10);
begin
select to_char(sysdate,'day')into pday from dual;--将今天是星期几赋值给 pday
dbms_output.put_line('今天是'||pday);--输出
if pday in ('星期六','星期天')then--判断是否是星期天 是就输出
dbms_output.put_line('休息日');
else
dbms_output.put_line('工作日');
end if;
end;
--for loop
declare
i int :=1;
begin
for i in 1..5 loop
dbms_output.put_line(i);--此处打印的是 for循环的i
end loop;
dbms_output.put_line(i);--这里打印的是 声明的变量i
end;
goto:直接跳出循环,不管有多少重 尽量少用,影响可读性。
null:代表一个空语句,什么都不执行,实际上没有意义
whlie
declare
v_num number:=11;
begin
while v_num<=20 loop
dbms_output.put_line(v_num);
v_num:=v_num+1;
end loop;
end;
%type:去前面标识符代表的数据类型
declare
i int :=1;
j i%type;--int型
begin
for i in 1..5 loop
dbms_output.put_line(i);--此处打印的是 for循环的i
j:=1;
end loop;
dbms_output.put_line(j);--这里打印的是 声明的变量i
end;
%rowtype:声明一行记录的变量
declare
emp_ty emp%rowtype;
begin
select * into emp_ty from emp where empno=7369;
dbms_output.put_line(emp_ty.empno||'--'||emp_ty.ename);
end;
cursors:游标 可理解为 resultset select语句
游标是 session的 你要自己定义一个游标,然后要给他一个名称,关联一个查询语句,通常返回多行
1.隐式游标 Implicit
隐式游标:
在PL/SQL中使用DML( Insert/Delete/Update/Select )语句时自动创建隐式游标,当前事物执行之后自动关 闭。隐式游标自动声明、打开和关闭,其名为 SQL,通过检查隐式游标的属性可以获得最近执行的 DML 语句的信息,隐式游标的属性有: %FOUND – SQL 语句影响了一行或多行时为 TRUE,%NOTFOUND – SQL 语句没有影响任何行时为TRUE,%ROWCOUNT – SQL 语句影响的行数,%ISOPEN - 游标是否打开,始终为FALSE
declare
sname1 student.sname%TYPE;
begin
select sname into sname1 from student;
if sql%found then
dbms_output.put_line(sql%rowcount);
else
dbms_output.put_line('没有找到数据');
end if;
exception
when too_many_rows then
dbms_output.put_line('查找的行记录多于1行');
when no_data_found then
dbms_output.put_line('未找到匹配的行');
end;
2.显式游标Explicit
定义好一个游标之后 用open操作
a,关联当前数据库,准备执行查询
b。开始查询
标识查询结果集
如果带有 for update子句。会锁定结果集的行,其他人就改不了状态
标记游标的位置在第一行的前面
%ifopen true false 打开之后不能再打开
%found null:游标打开之后 fetch之前返回null
true:最近一次fetch 有记录返归true 否则false
false:其他返回false
%notfound null:游标打开之后 fetch之前返回null
true:最近一次fetch 没有记录返归true 否则false
false:其他返回false
%rowcount
1.在游标open之后,在第一次fetch之前返回0;
2.其他情况返回抓取行数
declare
sname varchar2( 20); --声明变量
cursor student_cursor is select sname from student ; --声明游标
begin
open student_cursor; --打开游标
fetch student_cursor into sname; --让游标指针往下移动
while student_cursor%found --判断游标指针是否指向某行记录
loop --遍历
dbms_output.put_line ('学生姓名' ||sname );
fetch student_cursor into sname;
end loop;
close student_cursor;
end;
oracle SQL的特殊数据类型
rownum:伪列,虚拟列,查询的时候生成
rowid: 用于定位数据库中一条记录的一个相对唯一地址值。通常情况下,该值在该行数据插入到数据库表时即被确定且唯一。ROWID它是一个伪列,它并不实际存在于表中。它是ORACLE在读取表中数据行时,根据每一行数据的物理地址信息编码而成的一个伪列。所以根据一行数据的ROWID能找到一行数据的物理地址信息。从而快速地定位到数据行。数据库的大多数操作都是通过ROWID来完成的,而且使用ROWID来进行单记录定位速度是最快的。
select rownum,e.* from emp e;
select rownum,e.* from emp e where rownum<=5;
select * from
(
select rownum r,e.* from emp e where rownum<=10 可做分页,放入查询结果,不满足 rownum不变
)t where t.r > 5;
删除重复数据 留一条
delete from emp2 where empno in
(
select empno from emp2 group by empno having count(empno)>1
)
and rowid not in
(
select max(rowid) from emp2 group by empno having count(empno)>1
)
SEQUENCE:生成想生成的数字,用之前创建
INCREMENT BY 用于定义序列的步长,如果省略,则默认为1,如果出现负值,则代表序列的值是按照此步长递减的。
START WITH 定义序列的初始值(即产生的第一个值),默认为1。
MAXVALUE 定义序列生成器能产生的最大值。选项NOMAXVALUE是默认选项,代表没有最大值定义,这时对于递增序列,系统能够产生的最大值是10的27次方;对于递减序列,最大值是-1。
MINVALUE定义序列生成器能产生的最小值。选项NOMAXVALUE是默认选项,代表没有最小值定义,这时对于递减序列,系统能够产生的最小值是?10的26次方;对于递增序列,最小值是1。
CYCLE和NOCYCLE 表示当序列生成器的值达到限制值后是否循环。CYCLE代表循环,NOCYCLE代表不循环。如果循环,则当递增序列达到最大值时,循环到最小值;对于递减序列达到最小值时,循环到最大值。如果不循环,达到限制值后,继续产生新值就会发生错误。
CACHE(缓冲)定义存放序列的内存块的大小,默认为20。NOCACHE表示不对序列进行内存缓冲。对序列进行内存缓冲,可以改善序列的性能。
order:线程
create sequence myses;
drop sequence myse;
select * from tests for update;
insert into tests values(myses.nextval,'aaa',11,12456789,56);
如果一条sql出现myses.nextval 与myses.currval同时存在 myses.nextval先执行
如果一条sql出现2个myses.nextval 只执行一次
--存贮过程
create or replace procedure hello
is
begin
dbms_output.put_line('helloword');
end;
begin
hello;--MYSQL调用 存贮过程用 call oracle调用省略call直接调用
end;
--参数类型
create or replace procedure testPro
(
deptno1 emp.deptno%type
)
is
ss int :=0;
begin
select count(1) into ss from emp where deptno = deptno1;
dbms_output.put_line(ss);
end;
select * from emp;
begin
testPro(1);
end;
参数指定
create or replace procedure hellpro2
(
deptno1 emp.deptno%type default 10,
参数名称 数据类型 不能为null 默认default可选 实参形参要匹配
ss1 out int
参数模式: in out in out
in:默认模式 像常量 只读参数,当程序开始时,要么是形参的值,要么是默认值。一旦确定不可以更改 实参可以是一个常量 变量或其他表达式
out:必须收订指定。返回一个值给调用者。当程序开始时,形参接受调用者的调用,将实参给形参
)
is
begin
select count(1) into ss1 from emp where deptno = deptno1;
dbms_output.put_line(nvl(ss1,-1));
end;
declare
sss int :=1;
begin
hellpro2(2,sss);
end;
--函数
create or replace function myfun
(
deptno1 in emp.deptno%type default 10
)
return int
is
sss int :=0;
begin
select count(1) into sss from emp where deptno = deptno1;
return sss;
end;
select myfun (deptno1 => 10) from dual;
触发器:
经过命名的程序块存在数据库
跟存储过程不同的是,他是可启用或者禁用
不能显示调用 而是用什么触发
触发器不能有参数
处于可用状态,数据库自动调用 叫做:触发
触发条件
触发事件指的是同一个意思
基于表或视图的叫做DML 触发器
基于schema 或system的叫做DDL触发器
需要指定一个时间点
触发时间:在目标事件之前还是之后
触发效率:行级 (影响一行触发一次) 语句级(执行语句触发一次)默认是语句级
作用:1.自动生成虚拟列的值 rownum rowid
2.日志
3.阻止非法事物
触发器与约束的区别:
触发器跟约束一样 可以数据输入
触发器用于数据输入,本身有的数据影响不了
而约束可以影响所有的数据 当我们定义好一个约束 所以得数据中 一有不满足约束的数据 会马上报错
--触发器
create or replace trigger mytri
before delete on emp2 for each row
begin
dbms_output.put_line('delete a date');
end;
select * from emp2;
delete from emp2 where empno=7499;
--创建一个表用来存贮日志信息 删除或其他操作时 记录操作用户谁 干了什么
create table operlog
(
ids int primary key,
tableName varchar2(50),
oper varchar2(50),
opercount varchar2(50),
username varchar2(50),
cretetime date
)
drop trigger mytri;
create or replace trigger mytri2
before delete on emp2 for each row
begin
insert into operlog values(myses.nextval,'emp2','delete','',user,sysdate);
end;
select * from operlog
create table emp3 as select * from emp2 where 1<>1
select * from emp3
drop trigger mytri3
create or replace trigger mytri3
before delete on emp2 for each row
begin
insert into emp3 values(:old.empno,:old.ename,:old.job,:old.mgr,:old.hiredate,:old.sal,:old.comm,:old.deptno);
end;
create or replace trigger mytri4
before delete on emp2 referencing old as sss
for each row
begin
insert into emp3 values(:sss.empno,:sss.ename,:sss.job,:sss.mgr,:sss.hiredate,:sss.sal,:sss.comm,:sss.deptno);
end;
同一张表不能建两个触发器
oracle触发器主体不能写commit 语句
触发器越多效率越慢
可用触发器解决的也可以用 AOP来解决