Oracle数据库的学习

Oracle的存储过程(procedure)

创建

--存储过程定义 
create or replace procedure proce01(a in varchar2, b in out varchar2) 
as

begin
   -- b := a + b; -- 会将 字符转换为数值 ,注意a为in,所以不能被赋值,这与c里的函数不同
   b := a || b;
   dbms_output.put_line('a:'||a||'   b:'||b);
end proce01;

执行

-- 执行
declare 
     a  varchar2(20):= '01';
     b  varchar2(20):= 'bg';
begin  
    proce01(a ,b);
    dbms_output.put_line('a:'||a||'   b:'||b);
end;

输出结果:
a:01 b:01bg
a:01 b:01bg

删除

-- 删除存储过程
DROP PROCEDURE proce01

索引

-- 创建索引
create index DName_Index on dept(dname);
-- 删除索引
drop index Dname_index;

Oracle实现像Mysql的自动增长auto_increment

例如:

-- 建表:
CREATE TABLE t_user(U_ID NUMBER(8), UNAME VARCHAR2(20), UPASSWORD VARCHAR2(20));

-- 建立序列:
CREATE SEQUENCE SEQ_TUSER  
INCREMENT BY 1
MINVALUE 1                      --最小值  
MAXVALUE 99999999               --最大值由NUMBER(8)  
NOCYCLE                              --不打环   
NOCACHE                              --不缓存  
ORDER;
COMMIT;  

-- 然后建立before的触发器:
CREATE OR REPLACE TRIGGER TRG_ADDTUSER  
BEFORE INSERT ON t_user
FOR EACH ROW
BEGIN
SELECT SEQ_TUSER.NEXTVAL INTO :NEW.U_ID FROM DUAL;
END TRG_ADDTUSER;

-- 测试:
INSERT INTO t_user (UNAME,UPASSWORD) VALUES ('libai','589avf');
INSERT INTO t_user (UNAME,UPASSWORD) VALUES ('zhangsan','ko098');
COMMIT;
select * from t_user;

触发器Trigger

参考:https://blog.csdn.net/weixin_41649106/article/details/86981325

触发器的应用场景

  1. 复杂的安全性检查
  2. 数据的确认
  3. 数据库审计
  4. 数据的备份和审计

触发器例子1:update 之前进行安全检查

准备工作:

create table t_salary(id number(8), sal number(10,2));
insert  into t_salary(id, sal) values(1, 8000);
select * from t_salary;

创建触发器:

/**
涨后的薪水不能低于涨前的薪水
1 :old 和 :new 代表同一条记录
2 :old 代表操作该行之前,这一行的值
 :new 代表操作该行之后,这一行的值
*/
create or replace trigger checkSalary
 before update
 on t_salary
 for each row
declare
 -- local variables here 没有变量声明的话,declare可以省略
begin
 -- if 涨后的薪水 < 涨前的薪水 then 如何表示呢 ?
 if :new.sal < :old.sal then
   raise_application_error(-20002,'涨后的薪水:'|| :new.sal ||'小于涨前的薪水:'||:old.sal);
 end if;
end checkSalary;

测试:

SQL> update t_salary set sal=7000 where id=1;
update t_salary set sal=7000 where id=1
       *1 行出现错误:
ORA-20002: 涨后的薪水:7000小于涨前的薪水:9000
ORA-06512: 在 "SCOTT.CHECKSALARY", line 6
ORA-04088: 触发器 'SCOTT.CHECKSALARY' 执行过程中出错

删除触发器

--删除 触发器
drop trigger checkSalary;

例子2:备份数据

/*
删除前,将数据备份
*/
create or replace trigger tri_sal_delete_bk
  before delete
  on t_salary
  for each row
begin
  insert into t_salary_del(id,sal) values(:old.id, :old.sal);
  -- commit; -- 注意不可以有提交,会报错ora-04092
end tri_sal_delete_bk;

注意:DML(delete/update/insert)触发器中不能使用DDL(CREATE,DROP,ALTER)语句,也不能使用事务控制语句(ROLLBACK, COMMIT,SAVEPOINT)。特别注意的是,在触发器的主体中引用的函数(function)/过程(procedure)中也不能有事物控制语句。

例子3:

/**
非工作时间(星期六 星期日, 非9点~18点的区间)禁止写入数据
首先要搞清楚: 触发器的类型--语句级触发器。
不管插入了多少条数据,没有必要对每一行数据都进行校验,只要不在这个时间段内,都不让插入。
*/

create or replace trigger tri_addSalaryCheck
  before insert on t_salary
declare
 -- local variables here
begin
  if to_char(sysdate, 'day') in ('星期六', '星期日') or
      to_number(to_char(sysdate, 'hh24')) not between 9 and 18    then
      -- 禁止insert
      raise_application_error(-20001,'非工作时间禁止插入数据');
  end if;
end tri_addSalaryCheck;

定时器

例子

-- 定时器
-- ----------------------------
-- 创建表 JOBTEST
-- ----------------------------
-- DROP TABLE JOBTEST IF EXISTS ;
CREATE TABLE "JOBTEST" (
"LOCK_STATUS" VARCHAR2(2 BYTE) DEFAULT 'N'  NULL ,
"LOCK_DATE" TIMESTAMP(6)  NULL ,
"UN_LOCK_DATE" TIMESTAMP(6)  NULL 
);
COMMENT ON COLUMN "SCOTT"."JOBTEST"."LOCK_STATUS" IS 'Y 锁定 N 解锁';
COMMENT ON COLUMN "SCOTT"."JOBTEST"."LOCK_DATE" IS '加锁时间';
COMMENT ON COLUMN "SCOTT"."JOBTEST"."UN_LOCK_DATE" IS '解锁时间';

-- 
INSERT INTO "SCOTT"."JOBTEST" VALUES ('Y', TO_TIMESTAMP(' 2018-10-28 14:44:41:000000', 'YYYY-MM-DD HH24:MI:SS:FF6'), null);
INSERT INTO "SCOTT"."JOBTEST" VALUES ('Y', TO_TIMESTAMP(' 2018-10-28 14:44:52:000000', 'YYYY-MM-DD HH24:MI:SS:FF6'), null);
INSERT INTO "SCOTT"."JOBTEST" VALUES ('N', TO_TIMESTAMP(' 2018-10-28 14:45:01:000000', 'YYYY-MM-DD HH24:MI:SS:FF6'), null);

select * from jobtest;

-- Oracle定时器一般包括4步:
-- 1. 创建存储过程
CREATE OR REPLACE PROCEDURE unlockTest IS
BEGIN
	UPDATE JOBTEST
	SET LOCK_STATUS = 'N',
			UN_LOCK_DATE = SYSDATE
	WHERE LOCK_STATUS = 'Y' 
	AND SYSDATE > (LOCK_DATE + 10 /(24 * 60)); 
COMMIT ;
END ; 
-- unlockTest为存储过程的名称
-- BEGIN后面跟着的SQL就是要定时执行的SQL语句
-- 一定要记得在END之前添加COMMIT;(注意有分号)

-- 2. 定义执行时间
DECLARE
	unlockTest_timer number;
BEGIN
	SYS.DBMS_JOB.SUBMIT(
		job => unlockTest_timer, 
		what => 'unlockTest;', 
		next_date => SYSDATE, 
		interval => 'sysdate+10/(24*60)');
Commit;
End;
-- DECLARE 用来定义unlockTest_timer 的定时器编号
-- SYS.DBMS_JOB.SUBMIT中的job 指的是定时器编号,在DECLARE 中已经声明
-- SYS.DBMS_JOB.SUBMIT中的what 指的是要执行的存储过程,也就是SQL语句
-- SYS.DBMS_JOB.SUBMIT中的next_date 指的是下次执行时间
-- SYS.DBMS_JOB.SUBMIT中的interval 指的是每次执行时间的间隔时间

-- 3. 查看在执行的定时器(job是编号)
SELECT job, next_date, next_sec, failures, broken FROM user_jobs;

-- 4. 删除定时器
Begin
  dbms_job.remove(23); -- 23就是上面查出来的定时器编号
Commit;
End;

Oracle日期时间

转载:https://www.cnblogs.com/fubinhnust/p/9925720.html

-- Oracle时间
SELECT SYSDATE FROM  dual;  -- 系统时间   
SELECT SYSTIMESTAMP FROM  dual;  -- 当前系统时间戳
SELECT CURRENT_TIMESTAMP FROM  dual;  -- 与时区设置有关,返回的秒是系统的,返回的日期和时间是根据时区转换过的
SELECT current_date FROM  dual;  -- 是对CURRENT_TIMESTAMP准确到秒的四舍五入
select SYSDATE ,systimestamp,current_date,current_timestamp from dual;


-- 时间差计算
DECLARE
START_DATE DATE;
END_DATE DATE;
BEGIN
  START_DATE := SYSDATE - 1 ;
  END_DATE := SYSDATE  ;
  dbms_output.put_line('相差天数 :' || ROUND(TO_NUMBER(END_DATE - START_DATE)));
  dbms_output.put_line('相差小时数 :' || ROUND(TO_NUMBER(END_DATE - START_DATE) * 24));
  dbms_output.put_line('相差分钟数 :' || ROUND(TO_NUMBER(END_DATE - START_DATE) * 24 * 60));
  dbms_output.put_line('相差秒数 :' || ROUND(TO_NUMBER(END_DATE - START_DATE) * 24 * 60 * 60));
  dbms_output.put_line('相差毫秒数 :' || ROUND(TO_NUMBER(END_DATE - START_DATE) * 24 * 60 * 60 * 1000));
END;


-- 字符串转时间类型
SELECT to_date('2018-08-23 00:00:00','yyyy-mm-dd hh24:mi:ss') FROM dual;

-- 时间类型转字符串
select to_char(sysdate,'yyyy-mm-dd hh24::mi:ss') from dual;
select to_char(sysdate,'yyyy-mm-dd') from dual;


-- 时间日期加减
select sysdate,add_months(sysdate,12) from dual; --加1年
select sysdate,add_months(sysdate,1) from dual; --加1月
select sysdate,to_char(sysdate+7,'yyyy-mm-dd HH24:MI:SS') from dual; --加1星期
select sysdate,to_char(sysdate+1,'yyyy-mm-dd HH24:MI:SS') from dual; --加1天
select sysdate,to_char(sysdate+1/24,'yyyy-mm-dd HH24:MI:SS') from dual; --加1小时
select sysdate,to_char(sysdate+1/24/60,'yyyy-mm-dd HH24:MI:SS') from dual; --加1分钟
select sysdate,to_char(sysdate+1/24/60/60,'yyyy-mm-dd HH24:MI:SS') from dual; --加1秒
--------------------------------------------------------------------------------------
select sysdate,add_months(sysdate,-12) from dual; --减1年
select sysdate,add_months(sysdate,-1) from dual; --减1月
select sysdate,to_char(sysdate-7,'yyyy-mm-dd HH24:MI:SS') from dual; --减1星期
select sysdate,to_char(sysdate-1,'yyyy-mm-dd HH24:MI:SS') from dual; --减1天
select sysdate,to_char(sysdate-1/24,'yyyy-mm-dd HH24:MI:SS') from dual; --减1小时
select sysdate,to_char(sysdate-1/24/60,'yyyy-mm-dd HH24:MI:SS') from dual; --减1分钟
select sysdate,to_char(sysdate-1/24/60/60,'yyyy-mm-dd HH24:MI:SS') from dual; --减1秒

心静禅定ing
It is my decision,It is my life.
Oracle trunc()函数的用法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值