PL\SQL学习笔记
注释 单行--
多行
一.declare
一般用于做变量的申明.
begin 程序体开始执行 end; 程序体结束
exception ..
dbms_output.put_line('绝对值'||v_abs);输出语句
执行begin 之前必须先set serveroutput on;要不打印不出来
pl/sql约定俗成变量以v开头如 v_name
example:
declare
v_name varchar2(20) -----变量类型为变长字符
begin
v_name:='myname';------赋值 符号 :=
dbms_output.put_line(v_name);
end;
example2:
declare
v_num number :=0;
begin
v_num:=2/v_num;
dbms_output.put_line(v_num);
exception -----------0做除数会报异常
when others then
dbms_output.put_line('error');
end;
注意:oracle中dbms_output.put_line不能打印BOOLEAN类型否则回报错.
show user;命令显示当前用户 conn scott/tiger sconn为连接用户
oracle中变量类型
declae
v_temp number(1)---数字型 v-count binary_integer:=0;----整型一般做计数器用
v_sal number(5,2) :=40.00---小数型 v_date :=sysdate;---日期型
v_pi constant number(3,2):=3.14;---常量 v_valid boolean :=false;
v_name varchar2(20) not null :='my name'---不为空的变长字符
注意: 变量申明 使用%type属性 这样如果表中的字段属性变化 变量不用跟着变.
如v_empno2 com.comno%type; --com.conmo为com表中的字段
还可以以变量的属性定义变量如:v_empno3 v_empno2%type;
复合变量:
--table变量类型 表示数组
关键字 type 表示定义了一个类型 一般以type_开头 表示是新定义的类型
example:
declare
type type_table_emp_empno is table of emp.empno%type index by binary integer;
--index by binary integer表示数组下标由整数表示
v_empnos type_table_emp_empno;--定义一个变量是type_table_emp_empno类型
begin
v_empnos(0):=6666;--这里的0表示下标
v_empnos(-1):=7777;--oracle允许小标为负数
dbms_output.put_line(v_empnos(-1));
end;
--record变量类型 相当于JAVA中的类 里面有多个成员变量--dept是表名
declare
type type_record_dept is record
(deptno dept.deptno%type,
dname dcpt.dname%type,
ioc dept.ioc%type
);
v_temp type_record_dcpt;
begin
v_temp.deptno:=-50;
v_temp.dname:='dddd';
v_temp.ioc:='hj';
dbms_output.put_line(v_temp.dcptno||''||v_temp.dname);
end;
此时如果dept表增加或删除字段 维护起来麻烦可以使用
-- %rowtype申明record变量 取得一行数据 这张表的行有多少列怎么分他就怎么分
declare
v_temp dept%rowtype;
begin
v_temp.deptno:=-50;
v_temp.dname:='aaa';
v_temp.ioc:='hj';
dbms_output.put_line(v_temp.dcptno||''||v_temp.dname);
---------------------
plsql中sql语句的运用
select 语句不用游标必须有into 还必须保证有且只有一条记录多了没有都不行
declare
v_ename emp.ename%type;
v_sal emp.sal%type;
begin
select ename,sal into v_ename,v_sal from emp where empno=9999;
dbms_output.put_line(v_ename||''||v_sal);
end;
declare
v_deptno emp2.deptno%type :=50;
begin
update emp2 set sal=sal/2 where deptno=v_deptno;
dbms_output.put_line(sql%rowcount||'条记录被影响');
commit;
end;
--这里sql是关键字代表刚被执行的SQL语句%rowcount是SQL的属性表示影响了多少条记录
------------DDL语句如建表赋权限 immediate立即的..
begin
execute immediate 'create table t(nnn varchar(20) default ''aa'')';
end;
注意:DDL语句要加 execute immediate就OK了.
------------------------------
plsql循环.分支.......
--if语句
---取出7369的薪水,如果<1200 则输出'low' 如果<2000则输出'middle' 否则'high'
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---注意是elsif 不是else if
dbms_output.put_line('middle');
else dbms_output.put_line('high');---else后没有then
end if;
end;
-----循环
--do while循环
declare
i binary_integer:=1;
begin
loop
dbms_output.put_line(i);
i:=i+1;
exit when(i>=11);
end loop;
end;
-----while循环
declare
i binary_integer:=1;
begin
while i<11 loop
dbms_output.put_line(i);
i:=i+1;
end loop;
end;
---------for 循环
begin
for k in 1..10 loop
dbms_output.put_line(i);
end loop;
----从10到1逆序
for k in reverse 1..10 loop
dbms_output.put_line(i);
end loop;
end;
----------错误处理
declare
v_temp number(4);
begin
select cmpno into v_temp from emp where deptno=10;--deptno=10会返回多条记录
exception
when too_many_rows then----返回多条记录 的异常名字是too_many_rows
dbms_output.put_line('太多记录了');
when others then
dbms_output.put_line('error');
end;
declare
v_temp number(4);
begin
select cmpno into v_temp from emp where deptno=10;--deptno=10会返回多条记录
exception
when no_data_found then---没有找到数据异常
dbms_output.put_line('no data');
end;
----以下介绍DBA通常记录错误的做法 先建立一个错误日志表
create table errorlog
(
id number primary key,
errcode number,---出错代码
errmeg varchar2(1024),--出错信息
errdate date--出错时间
);
--主键自动递增
create sequence seq_errorlog_id start 1 increment by 1;
-----------
declare
v_teptno dept.deptno%type:=10;
v_errcode number;
v_errmsg varchar2(1024);
begin
delete from dept where deptno=v_deptno;
commit;
exception
when others then
rollback;
v_errcode:=SQLCODE;---SQLCODE是oracle关键字 表示出错代码
v_errmsg:=SQLERRM;---SQLERRM是oracle关键字 表示出错信息
insert into errorlog values(seq_errorlog_id.nextval,v_errcode,v_errrmsg,sysdate);
commit;
end;
-----------cursor 游标是一个指针 指向一个结果集就象迭代器 最开始指向结果集的top
declare
cursor c is
select * from emp;---申明一个游标 这时候ORACLE并不执行SELECT 只是申明
v_emp c%rowtype;
begin
open c;--打开游标ORACLE才执行SELECT
fetch c into v_emp;--从游标拿出一条数据游标自动往下移一格.. fetch取出的意思
dbms_output.put_line(v_emp.ename);
close c;
end;
declare
cursor c is
select * from emp;
v_emp c%rowtype;
begin
open c;
loop
fetch c into v_emp;
exit when (c%notfound);
dbms_output.put_line(v_emp.ename);
end loop;
close c;
end;
----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);
end loop;
close c;
end;
------------for 循环 不需要 定义v_emp 也不需要打开关闭游标 都是系统自动帮你做所以FOR循环最简单
declare
cursor c is
select * from emp;
begin
for v_emp in c loop
dbms_output.put_line(v_emp.ename);
end loop;
end;
------------带参数的游标
declare
cursor c(v_dempno emp.deptno%type,v_job emp.job%type)
is
select ename,sal from emp where deptno=v_dempno and job=v_job;
begin
for v_emp in c(30,'clerk') loop
dbms_output.put_line(v_emp.ename);
end loop;
end;
-----可更新的游标 一般游标是在SELECT中遍历结果集,有一种不常用的游标
----- 可做修改删除等操作... 关键字 forupdate->为了更新 current of c->当前游标所在这行
declare
cursor c is
select * from emp;
v_emp c%rowtype;
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;
----------------存储过程和一般的PLSQL块的区别就是
---create or replace procedure p is 代替了declare
create or replace procedure p
is
cursor c is
select * from emp2 for update;
begin
for v_emp in c loop
if(v_emp.deptno=10) then
update emp2 set sal =sal+10 where current of c;
elsif (v_emp.deptno=10) then
update emp2 set sal =sal+20 where current of c;
else
update emp2 set sal =sal+40 where current of c;
end if;
end loop;
commit;
end;
--执行过程有2个办法
--1 exec p;
---2 begin
p;
end;
-------------带参数的存储过程 参数类型 in 传入 out 传出 in out 传入传出 不写的话默认是in
create or replace procedure p
(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_b;--把传入的值赋给传出值v_ret
else
v_ret:=v_b;
end if;
v_temp:=v_temp+1;--v_temp即是传入又是传出 所以可以自己给自己赋值
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;
---注意创建存储过程出错系统不会告诉你哪里错了只会警告:创建的过程带有编译错误
--如果想知道出错位置和原因 输入命令:show error
-----function 必须有返回值
create or replace function sal_tax
(v_sal number)
return number
is
begin
if(v_sal<2000) then
return 0.1;
elsif(v_sal<2750) then
return 0.15;
else
return 0.20;
end if;
end;
--调用函数
select sal_tax(sal) from emp;
-----------------触发器 触发器不能单独执行必须依附在某张表上
create table emp2_log
(
uname varchar2(20),
action varchar2(10),
atime date
);-----此表是用来记录的即用触发器来记录表
create or replace trigger trig
after insert or delete or update no emp2 for each row--当在emp2这张表上插入更新删除时候会触发此触发器
--这里状态有after或berore 表示动作之后或之前
begin
if inserting then--inserting关键字代表当前正在插入操作
insert into emp2 values(USER,'insert',sysdate);--USER是关键字代表当前用户是谁
elsif updating then--updating关键字代表当前正在更新操作
insert into emp2 values(USER,'update',sysdate);
elsif deleting then--deleting关键字代表当前正在删除操作
insert into emp2 values(USER,'delete',sysdate);
end if;
end;
--注意for each row 是每一行都触发触发器比如更新6行触发6次触发器
--如果不加for each row 更新6行只触发1次触发器
--使用触发器 此触发器是在emp2这张表上插入更新删除时候会触发
update emp2 set sal=sal*2 where deptno=30;
--------------触发器的副作用
如:update dept set deptno=99 where deptno=10;
这个SQL语句是不能执行的 但是触发器可以实现
create or replace trigger trig
after update no dept for each row
begin
update emp set deptno=:NEW.deptno where deptno =:OLD.deptno;
end;
----
由此得知先触发触发器后检查完整性约束
-----------树状结构的存储与展示
就是字典表 有父ID
create table article
(
id number primary key,
cont varchar2(4000),
pid number,---父ID
isleal number(1),--0代表叶节点 1代表子节点
vlevel 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);
-----用存储过程调用自己来实现递归树
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_prestr||v_article.cont);
if(v_article.isleal=0) then
p(v_article.id,v_level+1);
end if;
end loop;
end;
执行:exec p(0,0);
PL\SQL学习笔记的更多相关文章
- ORALCE PL/SQL学习笔记
ORALCE PL/SQL学习笔记 详情见自己电脑的备份数据资料
- Oracle之PL/SQL学习笔记
自己在学习Oracle是做的笔记及实验代码记录,内容挺全的,也挺详细,发篇博文分享给需要的朋友,共有1w多字的学习笔记吧.是以前做的,一直在压箱底,今天拿出来整理了一下,给大家分享,有不足之处还望大家 ...
- [Oracle] PL/SQL学习笔记
-- 1. 使用一个变量 declare -- Local variables here v_name ); begin -- Test statements here select t.user_n ...
- PL/SQL学习笔记_01_基础
PL/SQL语句可以在Oracle客户端的 SQL窗口或者 command 窗口中运行 在SQL窗口中运行步骤同 SQL语句 在command 窗口中运行的步骤如下: 1)File—new com ...
- PL/SQL学习笔记程序单元
一:程序单元组成 一个PL/SQL程序单元主要包括三部分: 声明与定义部分:声明变量.常量.类型等:定义过程.函数等: 执行部分:执行PL/SQL语句:调用过程.参数:处理游标等: 异常处理部分:处理 ...
- PL/SQL学习笔记之日期时间
一:PL/SQL时间相关类型 PL/SQL提供两个和日期时间相关的数据类型: 日期时间(Datetime)数据类型 时间间隔类型 二:日期时间类型 datetime数据类型有: DATE TIMEST ...
- PL/SQL学习笔记之包
一:包 包是由一组相关的函数,过程,变量,游标等PL/SQL程序设计元素的组合而成的一个PL/SQL程序单元,相当于Java中的类. 包的主要作用是封装:把相同或相似的东西归类,方便维护和管理,提高开 ...
- PL/SQL学习笔记之集合
一:PL/SQL集合 集合是一个有序且存有相同的类型数据的数据结构. PL/SQL提供了三种集合类型: 索引表(关联数组) 嵌套表 数组 二:索引表:一个索引表(也叫关联数组)是一组键 - 值对.每个 ...
- PL/SQL学习笔记之异常
一:异常 程序执行过程中出现错误情况被称为异常,主要有两种类型的异常: 系统定义的异常 用户定义的异常 二:系统定义的异常 Exception Oracle Error SQLCODE 描述 ACCE ...
随机推荐
- elasticsearch 集群基本概念
cluster 代表一个集群,集群中有多个节点,其中有一个为主节点,这个主节点是可以通过选举产生的,主从节点是对于集群内部来说的.es的一个概念就是去中心化,字面上理解就是无中心节点,这是对于集群外部 ...
- htaccess 实现网址缩短
访问 :app.xxx.com/a 解析到:app.xxx.com/index.php/app/a <IfModule mod_rewrite.c> RewriteEngine on Re ...
- eclipse关联源码的方法
1.在项目的libs目录下,新建一个android-support-v4.jar.properties文件 2.打开android-support-v4.jar.properties,编辑. 输入源码 ...
- log4net发布时assembly引用错误的问题
网上的通行配置: 无论BS还是CS程序都可直接在项目的AssemblyInfo.cs文件里添加以下的语句: [assembly: log4net.Config .XmlConfigurator()] ...
- 杂音 & pop 音的解决方法
杂音 & pop 音的解决方法 1. 喇叭有严重的"吱吱"破音,绝大多数的原因有可能在于V(out)电压不稳定,所以最好测一下无负载时的输出电压.同时也可以测量 VCC – ...
- perl-cgi高级
来源: http://www.cnblogs.com/itech/archive/2012/10/07/2714393.html 一 CGI.pm中的方法(routines)调用 1. CGI.pm ...
- mysql innobackupex备份工具
先简单介绍一下这个工具:innobackupexinnobackupex比xtarbackup有更强的功能,它整合了xtrabackup和其他的一些功能,他不但可以全量备份/恢复,还可以基于时间的增量 ...
- IOS 中常用站位符
CGPoint.CGRect等可以转化为字符串打印出来 如: NSLog(@"-------------%@",NSStringFromCGPoint(point)); ...
- WPF子窗体:ChildWindow
wpf的子窗体选择有很多种,如最常见的是项目新建窗体(Window)作为子窗体 ,或者新建wpf用户控件(UserControl).而其实利用Xceed.Wpf.Toolkit.dll 可以轻松布局如 ...
- 将页面内容转为Excel下载
使用:method1(table); 说明:参数table为table元素的ID; var idTmr; function getExplorer() { var explorer = window. ...