Oracle定时器
ORACLE 9i及其以前版本,都是使用DBMS_JOB来实现任务调度。10g官方推荐使用DBMS_SCHEDULER。
1.1 JOB创建
1.1.1 先创建一个存储过程
create or replace procedure usp_test_pr
is
BEGIN update t_test set tname='test' where tid =110;
END;
1.1.2 在pl/sql developer中创建job
declare
v_job number;
begin
sys.dbms_job.submit(job=>v_job,
what => 'usp_test_pr;',
next_date => to_date('22-12-2008', 'dd-mm-yyyy'),
interval => 'sysdate+1/1440'); --每隔一分钟执行一次
commit;
end;
1.2 删除JOB
exec DBMS_JOB.remove(JOB=>&job_number);--输入job_number
commit;
1.3 查询所有的JOB
select * from dba_jobs j order by j.JOB desc
Over分析查询
Over函数,其实也可以转换成嵌套查询来实现。
准备测试数据
create table t_test( tid int, tname varchar2(20), tsalary number(8,2), tdeptno int, primary key(tid) );
begin
insert into t_test values(1,'小王',4500.21,3);
insert into t_test values(2,'小张',4200,3);
insert into t_test values(3,'小K',3000,3);
insert into t_test values(4,'小Q',8500.5,4);
insert into t_test values(5,'小T',1520.5,4);
insert into t_test values(6,'小丁',3000,5);
insert into t_test values(7,'小李',3000,5);
insert into t_test values(8,'小KK',3000,5);
end;;
SELECT * FROM T_TEST;
-----------------------------------------------------------------------------------------------
1 1 小王 4500.21 3
2 2 小张 4200.00 3
3 3 小K 3000.00 3
4 4 小Q 8500.50 4
5 5 小T 1520.50 4
6 6 小丁 3000.00 5
7 7 小李 3000.00 5
8 8 小KK 3000.00 5
--求工资占部门总工资额的比率
select tname, tsalary,tsalary/sum(tsalary)over(partition by tdeptno) per from t_test
-------------------------------------------------------------------------------------------
1 小王 4500.21 0.38462642978203
2 小张 4200.00 0.358967915960483
3 小K 3000.00 0.256405654257488
4 小Q 8500.50 0.848268635864684
5 小T 1520.50 0.151731364135316
6 小丁 3000.00 0.333333333333333
7 小李 3000.00 0.333333333333333
8 小KK 3000.00 0.333333333333333
--当然也可以不使用over,实现同样的效果
select a.tname,a.tsalary,a.tsalary/b.ttl per,a.tdeptno
from t_test a,(select tdeptno,sum(tsalary) ttl from t_test group by tdeptno) b
where a.tdeptno=b.tdeptno
1 小王 4500.21 0.38462642978203 3
2 小张 4200.00 0.358967915960483 3
3 小K 3000.00 0.256405654257488 3
4 小Q 8500.50 0.848268635864684 4
5 小T 1520.50 0.151731364135316 4
6 小丁 3000.00 0.333333333333333 5
7 小李 3000.00 0.333333333333333 5
8 小KK 3000.00 0.333333333333333 5
--求工资排名
SELECT ROWNUM ser ,TNAME,TSALARY,TDEPTNO
FROM(SELECT * FROM t_test order by tsalary desc)
--注意这样求出的排名,有点问题。就是工资一样的没有处于第一排名,这是由rownum的性质决定。
----------------------------------------------------------------------------------------------------
1 小Q 8500.50 4
2 小王 4500.21 3
3 小张 4200.00 3
4 小K 3000.00 3
5 小KK 3000.00 5
6 小李 3000.00 5
7 小丁 3000.00 5
8 小T 1520.50 4
--要实现真正的排名,应该使用rank或者dense_rank
-- rank()和dense_rank()的区别是:
--rank()是跳跃排序,有两个第二名时接下来就是第四名
--dense_rank()l是连续排序,有两个第二名时仍然跟着第三名
select dense_rank()over(order by tsalary desc) ser,tname,tsalary,tdeptno from t_test
------------------------------------------------------------------------
1 小Q 8500.50 4
2 小王 4500.21 3
3 小张 4200.00 3 4 小K 3000.00 3
4 小KK 3000.00 5
4 小李 3000.00 5
4 小丁 3000.00 5
5 小T 1520.50 4
--上面是工资在全体部门的排名,如果要求部门排名的话。
select tname,tsalary,tdeptno,dense_rank()over(partition by tdeptno
order by tsalary desc ) ser
from t_test
------------------------------------------------------------------------
1 小王 4500.21 3 1
2 小张 4200.00 3 2
3 小K 3000.00 3 3
4 小Q 8500.50 4 1
5 小T 1520.50 4 2
6 小丁 3000.00 5 1
7 小李 3000.00 5 1
8 小KK 3000.00 5 1
--直接实现行汇总
select tname,tsalary,tdeptno,sum(tsalary)over(partition by null) ttl from t_test
如下:
1 小王 4500.21 3 30721.21
2 小张 4200.00 3 30721.21
3 小K 3000.00 3 30721.21
4 小Q 8500.50 4 30721.21
5 小T 1520.50 4 30721.21
6 小丁 3000.00 5 30721.21
7 小李 3000.00 5 30721.21
8 小KK 3000.00 5 30721.21