Oracle学习笔记 (函数,视图,索引,存储过程)

当前用户创建了那些表,视图等。这个表叫做用户字典表
select table_name from user_tables;
select view_name from user_views;
select constraint_name,table_name from user_constraint;

declare 块用于声明变量
declare
v_name varchar2(20) :='zhoujian'; --变量默认v_开头
begin
v_name :='myName'; --赋值
dbms_output.put_line(v_name);
end


declare
v_name number:=0;
begin
v_num:=2/v_num;
dbms_output.put_line(v_num);
exception     --异常处理
when others then   --还有其他异常,则处理
  dbms_output.put_line('error');
end;
/

-------------------复合变量---------------------
table--相当于JAVA里面的数组
RECORD--相当于JAVA里面的类

table--

declare
  类型名称      下标类型
type type_table_emp_empno is table of emp.empno%type index by binary_integer;
  v_empnos type_table_emp_empno;
begin
v_empnos(0):=7369;
  v_empnos(2):=7839;
  v_empnos(-1):=0000;
  dbms_output.put_line(v_empnos(-1));
end;

RECORD--

declare
type type_record_dept is record
(
  deptno dept.deptno%type,
  dname dept.dname%type,
  loc dept.loc%type
);
v_temp type_record_dept;
begin
v_temp.deptno:=50;
  v_temp.dname :='aaaa';
  v_temp.loc:='bj';
  dbms_output.put_line(v_temp.deptno ||' '|| v_temp.dname);
end;

-- 使用%rowtype 声明record变量
declare
v_temp dept%rowtype;
begin
v_temp.deptno :=50;
  v_temp.dname :='aaaa';
  v_temp.loc:='bj';
  dbms_output.put_line(v_temp.deptno ||' '|| v_temp.dname);
end;


--------------------------------------------------
// 特定行类型,与该行的类型结构相同

declare
v_emp emp%rowtype;
begin
select * into v_emp from emp where empno=7369;
dbms_output.put_line(v_emp.ename);
end;
/

----------此段代码更新并且输出影响的行数---------
  1  declare
  2     v_deptno emp2.deptno%type:=20;
  3     v_count number;
  4  begin update emp2 set sal=sal/2 where deptno=v_deptno;
  5     -- 输出上一条SQL语句影响的行数
  6     dbms_output.put_line(sql%rowcount||'条记录被影响');
  7     commit;
  8* end;
SQL> /


begin
-- 立即,马上执行''内的SQL语句
-- 如遇单引号里仍有单引号,则两个单引号代表一个单引号。
execute immediate 'create table T(nnn varchar2(20) default ''aaa'')';
end

--------------------------------------------------

--------------------判断语句---------------------
// 判断语句的书写
declare
v_sal emp.sal%type;
begin
select sal into v_sal from emp where empno=7369;
if(v_sal<1200) then
  dbms_output.put_line('low');

-- 注意此处否则如果语法与一般程序语法不同
elsif(v_sal<2000) then
  dbms_output.put_line('middle');
else
  dbms_output.put_line('hight');
end if;
end;
/


--------------------------------------------------

--------------ORACLE里的循环--------------------

// ORACLE里的循环
-- 第一种(似DO WHILE)
declare
-- 二进制变量,默认为1
i binary_integer :=1;
begin
-- 循环开始
loop
  dbms_output.put_line(i);
  -- 变量自加
  i:=i+1;
  -- 在此条件下退出循环
  exit when (i>=11);
-- 循环结束
end loop;
end;

-- 第二种(似WHILE)
declare
j binary_integer:=1;
begin
// 条件  开始
while(j<11) loop
  dbms_output.put_line(j);
   j:=j+1;
end loop;
end;

-- 第三种(FOR)
begin
for k in 1..10 loop
  dbms_output.put_line(k);
end loop;
-- 反向输出
for k in reverse 1..99 loop
  dbms_output.put_line(k);
end loop;
end;


--------------------------------------------------


---------------异常处理--------------------
declare
v_temp number(4);
begin
-- select empno into v_temp from emp where deptno=10;
select empno into v_temp from emp where deptno=213;
exception
when too_many_rows then
  dbms_output.put_line('太多记录了');
when no_data_found then
  dbms_output.put_line('没有该数据');
when others then
  dbms_output.put_line('error');
end;
/

-- ORACLE数据库DBA使用一个表来记录数据库里的相应错误
create table errorlog
(
id number primary key,
errcode number,
errmsg varchar2(1024),
errdate date
)
/
-- 创建一个序列
create sequence seq_errorlog_id start with 1 increment by 1

-- 程序执行时
  1  declare
  2     v_deptno dept.deptno%type:=10;
  3     v_errcode number;
  4     v_errmsg varchar2(1024);
  5  begin
  6     delete from dept where deptno=v_deptno;
  7     commit;
  8  exception
  9     when others then
  -- 回撤已经执行的SQL
10             rollback;
   -- 将错误值赋予给相应变量
11                     v_errcode:=SQLCODE;
12                     v_errmsg:=SQLERRM;
  -- 将错误变量插入到错误记录表
13             insert into errorlog values(seq_errorlog_id.nextval,v_errcode,v_errmsg,sysdate);
14             commit;
15* end;

-- 具体出错时间
select to_char(errdate,'yyyy-mm-dd hh24:mi:ss') from errorlog
/


--------------------------------------------------

--------------------------------------------------

// 数据字典表
desc dictionary;

PLSQL
ORACLE内部的编程语言

PL是为了补充SQL语言的。SQL语言只有SDUI
过程,语言

输出HelloWorld
begin
dbms_output.put_line('HelloWorld');
end;
/

--------------------存储过程------------------------
1.创建存储过程
  S P

// 设置显示输出
set serveroutput on;

// 创建一个存储过程
create or replace procedure test
is
v_sal number;
begin
select sal into v_sal from emp where empno=7900;
dbms_output.put_line(v_sal);
end test;

// 执行
exec test;

begin
test;
end;
/

-- 带参
create or replace procedure p
-- in 传入 out 传出
(v_a in number,v_b number,v_ret out number, v_temp in out number)
is
begin
if(v_a>v_b) then
  v_ret:=v_a;
else
  v_ret:=v_b;
end if;
v_temp:=v_temp+1;
end;
/

-- 调用
declare
v_a number:=3;
v_b number:=4;
v_ret number;
v_temp number:=5;
begin
p(v_a,v_b,v_ret,v_temp);
dbms_output.put_line(v_ret);
dbms_output.put_line(v_temp);
end;
/



// 删除
drop procedure test;

----------------------------------------------------

----------------------视图--------------------------

// 创建
create or replace view 视图名称 as 子查询
with check option --加此将不能修改条件列
with read only  --整个视图都是只读的

// 视图是一个虚拟表

// 删除
drop view test;

----------------------------------------------------

----------------------函数--------------------------
create or replace function 函数名 is
v_sal number;
begin
select * from emp;
end;

-- 带返回值的函数
  1  create or replace function sal_tax
  2     (v_sal number)
  3     return number
  4  is
  5  begin
  6     if(v_sal<2000)then
  7             return 0.10;
  8     elsif(v_sal<2750)then
  9             return 0.15;
10     else
11             return 0.20;
12     end if;
13* end;
SQL> /

dr

// 调用函数
select 函数名(参数名)from dual;

// 删除函数
drop function sal_tax;

----------------------------------------------------
---------------------游标---------------------------
-- do while循环
declare
-- 申明一个游标
cursor c is
  select * from emp;
v_emp c%rowtype;
begin
-- 打开游标(此时才取出数据)
open c;
-- 循环游标(do while)
loop
  fetch c into v_emp;
   -- 如果没有找到返回记录
   exit when (c%notfound);
   dbms_output.put_line(v_emp.ename);
end loop;
close c;
end;
-- rowcount 返回记录数 found找到的记录数 notfound

-- while 循环
declare
-- 申明一个游标
cursor c is
  select * from emp;
v_emp c%rowtype;
begin
-- 打开游标(此时才取出数据)
open c;
fetch c into v_emp;
while (c%found) loop
  dbms_output.put_line(v_emp.ename);
  fetch c into v_emp;
end loop;
close c;
end;

-- for循环
declare
cursor c is
  select * from emp;
begin
-- 自动申明,自动打开关闭。自动fetch,自动放入v_emp
for v_emp in c loop
  dbms_output.put_line(v_emp.ename);
end loop;
end;

-- 带参数的游标
declare
  -- 形参
cursor c(v_deptno emp.deptno%type,v_job emp.job%type)
is
  select ename,sal from emp where deptno=v_deptno and job =v_job;
-- 不需要申明
--v_temp c%rowtype;
begin
for v_temp in c(30,'CLERK') loop
  dbms_output.put_line(v_emp.ename);
end loop;
end; 

-- 可更新的游标
declare
cursor c
is
  select * from emp2 for update;
begin
for v_temp in c loop
  if(v_temp.sal<2000)then
   -- 更新当前这条记录
   update emp2 set sal=sal*2 where current of c;
  elsif (v_temp.sal=5000) then
   delete from emp2 where current of c;
  end if;
end loop;
commit;
end;

----------------------------------------------------
---------------------触发器------------------------
--触发器不能直接执行,它必须依附在某张表上面
--创建一张表(记录表)
SQL> create table emp2_log
  2  (
  3  uname varchar2(20),
  4  action varchar2(10),
  5  atime date
  6  );

-- 创建触发器
create or replace trigger trig
-- 此处代表此触发器出发的条件,其中after可以用BEFORE替代。
-- 此处如果不写FOR EACH ROW 则执行多次时只触发一次,写了之后,执行一条则触发一次。
after insert or delete or update on emp2 for each row
begin
if inserting then
  insert into emp2_log values (user,'insert',sysdate);
elsif updating then
  insert into emp2_log values (user,'update',sysdate);
elsif deleting then
  insert into emp2_log values (user,'update',sysdate);
end if;
end;
/

-- 删除触发器
drop trigger trig
/

-- 触发时更新关联表
-- 先触发,后约束
create or replace trigger trig
after update on dept
for each row
begin
--   新值   旧值
update emp set deptno=:new.deptno where deptno=:old.deptno;
end;
/


----------------------------------------------------
--------------树状结构的存储和展示------------------

--
create table article(
id number primary key,
cont varchar2(4000),
pid number,
isleaf number(1), --0代表非叶子节点,1代表叶子节点
alevel number(2)
);

insert into article values(1,'蚂蚁大战大象',0,0,0);
insert into article values(2,'大象被打趴下了',1,0,1);
insert into article values(3,'蚂蚁也不好过',2,1,2);
insert into article values(4,'瞎说',2,0,2);
insert into article values(5,'没有瞎说',4,1,3);
insert into article values(6,'怎么可能',1,0,1);
insert into article values(7,'怎么没有可能',6,1,2);
insert into article values(8,'可能性是很大的',6,1,2);
insert into article values(9,'大象进医院了',2,0,2);
insert into article values(10,'护士是蚂蚁',9,1,3);
commit;

-- 递归调用
create or replace procedure p(v_pid article.pid%type,v_level binary_integer) is
cursor c is select * from article where pid=v_pid;
v_preStr varchar2(1024):=' ';
begin
for i in 1..v_level loop
  v_preStr:=v_preStr||'****';
end loop;
for v_article in c loop
  dbms_output.put_line(v_article.cont);
  if(v_article.isleaf=0)then
   p(v_article.id,v_level+1);
  end if;
end loop;
end;
/


----------------------------------------------------

你可能感兴趣的:(oracle,sql,C++,c,C#)