oracle模式与pl/sql简析
好书推荐:赵振平老师的oracle11g学习笔记
这段时间天天纠结于论文 修改 修改 还是修改 漫长、痛苦、而又纠结的过程 有时间看看书 整理下所见所得 感到非常的舒服了 记录学习的脚步
模式是数据库对象的集合,包括很多对象,常见的表、视图、存储过程、函数、触发器、包、包体、序列、同义词等等,按照赵老师的话即是模式名就是用户名,用户名就是模式名
下图模式的所有对象
下面即是记录学习笔记的东西 必要的地方以加了注释
--创建表 create table STUS ( stu_id VARCHAR2(50) not null, stu_name VARCHAR2(30) not null, stu_age NUMBER not null, stu_birthday DATE not null, primary key(stu_id) ) --添加数据 insert into stus values(sys_guid(),'sz',21,sysdate); insert into stus values(sys_guid(),'gz',20,sysdate); insert into stus values(sys_guid(),'sh',19,sysdate); commit; --删除表中数据 delete from stus; commit; --查询表中数据 select * from stus; --模式(Schema)-->是数据库对象的集合(包括)(模式名就是用户名,用户名就是模式名) --创建视图 --视图作用:简化了sql语句、加强了表的安全访问、简化了数据访问的复杂性 --创建只读视图 不能通过视图对基表进行相应的增删改 只能进行查询 create or replace view v_stus as select * from stus where stu_age=20 with read only; --视图中也可以增删改查 create or replace view v_stus_crud as select * from stus where stu_age=19; --测试通过视图删除基表中的数据 select * from v_stus; select * from v_stus_crud; delete from v_stus_crud; commit; --查看视图的结构 desc v_stus; --查看视图的结构 select dbms_metadata.get_ddl('VIEW','V_STUS_CRUD','UNDER') from dual; --删除视图 如果有参照完整性的话 则需要加上cascade constraints drop view v_stus_crud cascade constraints; --动态创建sql语句 create or replace procedure pro_stus Authid Current_User --在存储过程中 用户的权限是不可用的 需要使用Authid Current_User才能显示的获得权限 as v_sql varchar2(100); begin v_sql:='create or replace view v_stus as select * from stus where stu_age=19 with read only'; execute immediate v_sql; end; / --在sql*plus中测试存储过程 execute pro_stus; --查看系统用户 select * from dba_users where username='GA_NEW'; --查看用户权限 select * from role_sys_privs; --查看角色所拥有的权限 select * from dba_sys_privs where grantee='RESOURCE'; --创建序列 create sequence seq_stus increment by 1 start with 1 nomaxvalue nominvalue nocache nocycle order --currval 获取序列当前值 select seq_stus.currval from dual; --nextval 获取下一个值 select seq_stus.nextval from dual; drop sequence seq_stus; --创建同义词(隐藏对象名) --分为共有的和私有的 create synonym ps for stus; select * from ps; select * from stus; --删除同义词 drop synonym ps; --打开控制台输出 set serveroutput on; --pl/sql是一个过程化的语言,属于第三代语言 --pl/sql语句块的执行 ---过程化的语句由pl/sql过程化的语句执行器处理 ---sql语句由oracle的sql语句执行器执行 --pl/sql单元的特点(安全、执行效率高、易于扩展、面向对象) --pl/sql单元包括block、function、procedure、package、package body、trigger、type、type body 8个组成 /* 多行注释 [declare] begin [exception] end */ declare v_a binary_integer; --变量 c_a constant number :=100; --常量 begin v_a := 20; dbms_output.put_line('变量的值为:' || v_a || '常量的值为:' || c_a); end; / --测试变量的作用域 declare m number :=22; begin declare m number :=39; begin dbms_output.put_line('变量的值为' || m ); end; dbms_output.put_line('变量的值为' || m ); end; / --绑定变量(在sql*plus中创建 在sql*plus、sql、pl/sql中能够使用) variable v_db varchar2(100); begin :v_db := '2345'; end; / print v_db; --在sql语句中使用,但是需要在sql*plus中进行执行 begin :v_db := 'gz'; end; / select * from stus where stu_name=:v_db; --自定义类型 declare subtype small_num is number(4,1); v_test small_num; begin null; end; / --char varchar varchar2 --char比varchar的效率要高 但是浪费存储空间 性价比最好的即是varchar2 --pl/sql null表示什么也不做 create or replace procedure pro_test as v_null varchar2(20); begin v_null :=null; if v_null is null then dbms_output.put_line('变量为空值'); else dbms_output.put_line('变量不为空值'); end if; end; / --if then elsif else end if create or replace procedure pro_test2(v_name in varchar2) as v_age stus.stu_age%type; begin select stu_age into v_age from stus where stu_name = v_name; if v_age<15 then dbms_output.put_line('年龄小于15'); elsif v_age<=18 then dbms_output.put_line('年龄在15--18之间'); else dbms_output.put_line('年龄大于18'); end if; end; / --case when then create or replace procedure pro_test3(v_name in varchar2) as v_age stus.stu_age%type; begin select stu_age into v_age from stus where stu_name =v_name; --if语句 if v_age is null then dbms_output.put_line('找不到数据'); else --case 语句 case when v_age<15 then dbms_output.put_line('年龄小于15'); when v_age<=18 then dbms_output.put_line('年龄在15-18之间'); else dbms_output.put_line('年龄大于18'); end case; end if; --处理异常 exception when no_data_found then dbms_output.put_line(v_age||' 错误代码为: '||sqlcode|| ' 错误的描述为:' ||sqlerrm); end; / --loop end loop create or replace procedure pro_test4(v_c in binary_integer) as -- v_age stus.stu_age%type; v_count binary_integer :=v_c; begin /* loop exit when v_count>10; v_count :=v_count+1; dbms_output.put_line(v_count); end loop; */ while v_count<10 loop exit; v_count :=v_count+1; dbms_output.put_line('while结果集:'||v_count); end loop; for vc in v_count..10 loop dbms_output.put_line(vc); end loop; end; / --goto 标签 create or replace procedure pro_test5 as v_count binary_integer :=0; begin <<l1>> v_count := v_count+1; loop dbms_output.put_line('goto语句:'||v_count); exit when v_count>4; goto l1; end loop; end; / --exception 异常 create or replace procedure pro_test6 as my_exc exception; pragma exception_init(my_exc,-20473); begin --raise my_exc; raise_application_error(-20473,'自定义的异常错误描述符'); -- -20000-->-20999 exception when my_exc then dbms_output.put_line('自定义异常' || sqlcode || sqlerrm); end; / --游标 --隐式游标和显示游标 --隐式游标的四个属性----> sql%found sql%notfound sql%rowcount sql%isopen create or replace procedure pro_test7 as begin delete from stus; if sql%found then commit; else null; end if; end; / --显示游标 分为静态游标和动态游标(游标变量) --游标操作四步骤 游标定义 打开游标 获取数据 关闭游标 create or replace procedure pro_test8(va in number) as v_name stus.stu_name%type; cursor cur_stus(v_age number) is select stu_name from stus where stu_age>v_age; begin open cur_stus(va); loop fetch cur_stus into v_name; exit when cur_stus%notfound; dbms_output.put_line(v_name); end loop; close cur_stus; end; / -- %type(某个字段的类型) %rowtype(某一行的类型) --动态游标 create or replace procedure pro_test9(input_num in number) as type my_cur is ref cursor; --声明了一个游标类型 v_cur my_cur; rec stus%rowtype; begin case input_num when 1 then open v_cur for select * from stus; else open v_cur for select * from stus where stu_age>19; end case; loop fetch v_cur into rec; exit when v_cur%notfound; dbms_output.put_line('结果为:'||rec.stu_id||' '||rec.stu_name); end loop; close v_cur; end; / --使用for in 输出游标的内容 create or replace procedure pro_test9 as cursor cur_stus is select * from stus; begin for rec in cur_stus loop dbms_output.put_line(rec.stu_name); end loop; end; / --触发器使用java、c、pl/sql编写的程序单元, --存储于数据库中,能够被触发事件(dml([update or insert or delete of 字段])/ddl/system event/user event)触发从而执行特定的动作 --触发事件 create trigger 触发器名称 before/after/instead of 事件 on 表名/视图名/数据库 [for each row] --触发限制 [when (条件)] --触发动作 begin null; end; /* 触发器的分类--行级触发、语句级触发 before触发、after触发 compound触发(拥有四个时间点,语句前后、行级前后、比较特殊) instead of触发(用于更新视图) system event、user event 在触发动作区域,在行级触发时,可以使用(:new.列名 :old.列名 访问列值 可使用referencing进行重命名 eg: referencing new as new_one) */ create or replace trigger stu_trigger after update on stus referencing new as new_val old as old_val for each row begin dbms_output.put_line('新值' || :new_val.stu_name); dbms_output.put_line('旧值' || :old_val.stu_name); end; / update stus set stu_name='gz' where stu_age=20; commit; alter trigger stu_trigger disable; alter trigger stu_trigger enable; drop trigger stu_trigger; --动态sql语句 --只有在运行的时候才知道内容 两种方式执行(本地动态sql execute immediate 或者 dbms_sql) --静态sql语句--内容已经确定 为pl/sql的一部分 --用dll语句创建对象时 建议使用||来进行连接 不推荐使用绑定对象 --在进行动态sql语句返回值 可分为三种情况 --返回单行单列的值 返回单行多列的值 返回多行多列的值 --返回单行单列的值 create or replace procedure shsl_pro Authid Current_User as sql_string varchar2(100); v_max_age number; begin sql_string :='select max(stu_age) from stus where stu_name=:a'; execute immediate sql_string into v_max_age --返回值放入变量中 using 'gz'; --替换使用占位符的参数 dbms_output.put_line(v_max_age); end; / --返回单行多列的值 create or replace procedure shdl_pro Authid Current_User as sql_string varchar2(100); v_max_age number; v_stu_id varchar2(100); begin sql_string :='select stu_age,stu_id from stus where stu_name=:a'; execute immediate sql_string into v_max_age,v_stu_id using 'gz'; dbms_output.put_line(v_max_age||' '||v_stu_id); end; / --返回多行多列的值 create or replace procedure dhdl_pro Authid Current_User as sql_string varchar2(100); type v_cursor is ref cursor; dhdl_cursor v_cursor; rec stus%rowtype; begin sql_string :='select * from stus where stu_age > :a'; open dhdl_cursor for sql_string using 18; loop exit when dhdl_cursor%notfound; fetch dhdl_cursor into rec; dbms_output.put_line(rec.stu_id||' '||rec.stu_name); end loop; close dhdl_cursor; end; / --存储过程 执行效率高、隐藏数据、减少通信量 --独立子程序和包子程序 --%type %rowtype 可以间接的获取数据类型 --在sql*plus中执行存储过程 exec 存储过程名(参数列表) --在块中 存储过程名(参数列表) begin dhdl_pro; end; / --存储过程重新编译 alter procedure dhdl_pro compile; drop procedure dhdl_pro; --函数(function)必须有返回值 create or replace function func_test1(iid varchar2) return number as v_age stus.stu_age%type; begin select stu_age into v_age from stus where stu_id=iid; return(v_age); end; / select func_test1('E85587EB4C594395B681C068F046724E') from dual; alter function func_test1 compile; drop function func_test1; --包由包头(包的说明部分)和包体(包的主体)组成 提高数据安全性、加快模块化开发、提高程序的执行性能 create or replace package pac_test as type my_cursor is ref cursor; procedure pro_pac(iid in varchar2); end; / create or replace package body pac_test as procedure pro_pac(iid in varchar2) as v_age stus.stu_age%type; begin select stu_age into v_age from stus where stu_id=iid; dbms_output.put_line('结果为:' || v_age); end; end; / drop package pac_test; drop package body pac_test; --包中存储过程与函数的重载(参数个数/参数类型) --重载的函数的返回值类型不一致 也不能算为重载 --存储过程的参数的模式不一样不能重载 --重载函数的的参数的类型不能属于同一组类 例如 char与varchar2 --测试 create or replace package pac_over1 as procedure p(ipara in varchar2); procedure p(ipara out varchar2); end; / create or replace package body pac_over1 as procedure p(ipara in varchar2) as begin dbms_output.put_line('输入参数' || ipara); end; procedure p(ipara out varchar2) as begin ipara := 'test'; end; end; / create or replace package pac_over as procedure p(iid in varchar2); procedure p(iid2 out char); end; / create or replace package body pac_over as procedure p(iid in varchar2) as begin dbms_output.put_line('测试重载存储过程1'); end; procedure p(iid2 out char) as begin dbms_output.put_line('测试重载存储过程2'); iid2 :='c'; end; end; / create or replace procedure pro_test_pac as v_test char; begin pac_over.p2(v_test); dbms_output.put_line(v_test); end; / create or replace procedure pro_debug as v_a number :=10; c_a constant binary_integer :=20; begin v_a := v_a+c_a; dbms_output.put_line('结果为:' || v_a); end; /
附上存储过程的调试 也是很有用的东西
创建测试存储过程
create or replace procedure pro_debug as v_a number :=10; c_a constant binary_integer :=20; begin v_a := v_a+c_a; dbms_output.put_line('结果为:' || v_a); end; /
上图选中你要调试的存储过程 点击test
点击上图或者f9开始调试 点下图
进入单步调试模式 两次
进入到存储过程里面
你可以设置断点 即 在想要加上断点的那一行开头行号数字那鼠标左键双击即可
查看变量 在Variable那一列输入你想要查看变量的名称 在调试的过程中 即可看到变量的变化值
在存储过程外调试 查看变量的值也是一样的 函数、触发器 的调试过程也是类似的
posted on 2014-04-19 15:22 liangxinzhi 阅读(142) 评论(0) 编辑 收藏 举报