一.pl/sql基础

pl/sql分匿名块和命名块.

命名块:存储过程,函数,触发器,包等.

pl/sql语句块分3部分:

(1)声明部分

(2)可执行部分

(3)异常处理部分

其中可执行部分是语句块中唯一要求必须存在的部分,声明部分和异常处理部分是可选的。

1.匿名块语法:

DECLARE

declaration statements

BEGIN

executable statements

EXCEPTION

exception-handing statements

END;

2.声明变量

语法:

identifier [CONSTANT] datatype [NOT NULL] [:= value | DEFAULT expr]

声明变量方法1:

declare

v_first_name varchar2(50);

c_count   constant number :=0;  ---常量

v_hiredate  date;

v_valid   BOOLEAN NOT NULL DEFAULT TRUE;

声明变量方法1:

declare

v_ename emp.ename%type;

v_sal emp.sal%type;

//显示雇员的姓名,工资,个人所得税set serveroutput on;

declare

v_ename varchar2(20);

v_sal number(6,2);

c_tax_rate constant number(3,2) :=0.06; ---税率

v_tax_sal number(6,2);

begin

select ename,sal into v_ename,v_sal from emp where empno = &no;

v_tax_sal := v_sal * c_tax_rate; ---赋值

dbms_output.put_line('v_ename: ' || v_ename);

dbms_output.put_line('v_sal: ' || v_sal);

dbms_output.put_line('v_tax_sal: ' || v_tax_sal);

end;

3.标识符的命名规则

(1)定义变量,建议用v_,如v_ename

(2)定义常量,建议用c_,如c_tax_rate

(3)定义游标,建议用_cursor作为后缀,如emp_cursor

(4)定义表类型,建议用_table_type作为后缀,如sal_table_type;

(5)定义表变量,建议用_table作为后缀,例如sal_table;

4.PL/SQL编译过程步骤

编译过程包括语法检查,绑定以及为代码生成。语法检查涉及检查PL/SQL代码中的编译错误。在纠正语法错误之后,会给每个变量分配内存地址,以保存ORACLE数据,这个过程成为绑定。接下来,会产生PL/SQL语句块的伪代码,伪代码是PL/SQL引擎的指令列表,对于命名语句块,伪代码会存储在数据库中,并在程序下一次执行时使用。

5.替代变量

在匿名PL/SQL块中接受输入参数使用&或者&&作为替代变量

6.初始化变量用select into语法//求emp表中的平均工资

SQL> set serveroutput on;

SQL>

SQL> declare

2 v_avg_sal number(6,2);

3 begin

4 select avg(sal) into v_avg_sal from emp;

5 dbms_output.put_line('v_avg_sal: ' || v_avg_sal);

6 end;

7 / ---表示执行

v_avg_sal: 2530.88

PL/SQL procedure successfully completed.

二.控制语句

7.if语句

if语法:

IF condition THEN

statements;

[ELSIF condition THEN

statements;]

[ELSE

statements;

]

END IF;

//如果工资小于2000,把雇员的薪水加薪50setserveroutput on;

declare

v_sal emp.sal%type;

begin

select sal into v_sal from emp where lower(ename)=lower('&name');

if v_sal <2000 then

update emp set sal=sal+50 where lower(ename)=lower('&name');

end if;

end;

//如果job=PRESIDENT,sal=sal+200

job=MANAGER ,sal=sal+1000

other ,sal=sal+100setserveroutput on;

declare

v_job emp.job%type;

v_empno emp.empno%type;

begin

select job,empno into v_job,v_empno from emp where empno=&no;

if v_job='PRESIDENT' then

update emp set sal=sal+200 where empno=v_empno;

elsif v_job='MANAGER' then

update emp setsal=sal+1000 where empno=v_empno;

else

update emp set sal=sal+100 where empno=v_empno;

endif;

commit;

end;

8.循环语句

//loop循环

loop

statements;

exit [when condition];

end loop;

//例子create table tmp01 (id int);

declare i int :=1;

begin

loop

insert into tmp01 values (i);

commit;

exit when i >100;

i := i+1;

end loop;

end;

//while循环

while condition loop

statement1;

statement2;

......

end loop;

//例子declare i number :=1;

begin

while i <100 loop

insert into tmp01 values (i);

i := i+1;

end loop;

commit;

end;

//FOR循环

for counter in [reverse] lower_bound .. upper_bound loop  ---counter变量不需要定义

statement1;

statement2;

......

end loop;

//例子begin

for i in 1..100 loop

insert into tmp01 values (i);

end loop;

commit;

end;

//用替代变量输入部门号,使用case语句判断条件更新雇员工资

部门号为10,雇员加薪10%

部门号为20,雇员加薪8%

部门号为30,雇员加薪15%

如果输入其他数字,则显示“该部门不存在”declare

v_deptno emp.deptno%type;

begin

v_deptno := &deptno;

case v_deptno

when 10 then

update emp set sal=sal*1.1 where deptno=v_deptno;

when 20 then

update emp set sal=sal*1.08 where deptno=v_deptno;

when 30 then

update emp set sal=sal*1.15 where deptno=v_deptno;

else

dbms_output.put_line('deptno not exists');

end case;

end;

9.SQL游标

当执行select,insert,update,delete时,oracle会为SQL语句分配相应的上下文区域(context area).oracle使用上下区域解析并执行相应的SQL语句,而游标就是指向上下文区域的指针。

游标包括隐式游标和显示游标。其中隐式游标也称为SQL游标,专门用于处理select into,insert,update,delete语句。显示游标用于处理多行select语句。

SQL游标属性:sql%found,sql%notfound,sql%rowcount,sql%isopen等

(1)sql%isopen:用于确定SQL游标是否打开。

(2)sql%found:用于确定SQL语句是否执行成功。

(3)sql%notfound:用于确定SQL语句是否执行成功。

(4)sql%rowcount:用于返回SQL语句所作用的总计行数。

//例子1set serveroutput on;

declare

v_deptno emp.deptno%type := &no;

begin

update emp set sal = sal*1.05 where deptno=v_deptno;

if sql%notfound then

dbms_output.put_line('deptno is not exist.');

else

dbms_output.put_line('sql execute successful.');

end if;

end;

//例子2set serveroutput on;

declare

v_deptno emp.deptno%type := &no;

begin

update emp set sal = nvl(sal,0)*1.05 where deptno=v_deptno;

dbms_output.put_line('have '|| sql%rowcount || ' row have change.');

if sql%notfound then

dbms_output.put_line('deptno is not exist.');

else

dbms_output.put_line('sql execute successful.');

end if;

end;

10.例子

用替代变量输入客户名(不区分大小写)和所在城市,并修改客户所在城市,如果客户不在,则显示“该客户不在”

客户名:yangry

city:henan+---创建表

create table customer(customer_id number not null,customer_name varchar2(50),

city_name varchar2(50) ,constraint pk_customer primary key(customer_id));

---代码

set serveroutput on;

declare

v_name customer.customer_name%type;

v_city customer.city_name%type;

begin

v_name := '&customer_name';

v_city := '&city_name';

update customer set city_name=v_city where upper(customer_name)=upper(v_name);

if sql%notfound then

dbms_output.put_line('customer is not exist.');

end if;

commit;

end;

三.PL/SQL集合

(1)索引表(Associative arrays, also known as index-by tables)

(2)嵌套表

(3)变长数组

用于处理多行单列数据

(4)PL/SQL记录表

处理多行多列数据

1.pl/sql记录

TYPE type_name IS RECORD(

field_declaration1[,field_declaration2]...

);

identifier type_name;

type_name:记录类型的名称(IS RECORD 表示记录类型)

field_declaration:记录成员的定义,多个记录成员之间用逗号(,)隔开.

identifier:指定记录变量名

定义pl/sql记录方法1:

type emp_record_type is record (

names emp.ename%type,

salary emp.sal%type,

dno emp.deptno%type

);

---emp_record是基于记录类型emp_record_type所定义的记录变量

emp_record emp_record_type;

定义pl/sql记录方法2:

%rowtype属性可以基于表或者视图定义记录变量

identified table_name%rowtype;

or

identified view_name%rowtype;

dept_record dept%rowtype;

----ename,sal,dno

---替代变量用eno---empno

dbms_output.put_line(emp_record.names);

set serveroutput on;

declare

type emp_record_type is record(

names emp.ename%type,

salary emp.sal%type,

dno emp.deptno%type

);

emp_record emp_record_type;

begin

select ename,sal,deptno into emp_record from emp where empno=&no;

dbms_output.put_line('names: ' || emp_record.names);

dbms_output.put_line('salary: ' || emp_record.salary);

dbms_output.put_line('dno: ' || emp_record.dno);

end;

---在select into语句中使用记录成员set serveroutput on;

declare

type emp_record_type is record(

names emp.ename%type,

salary emp.sal%type,

dno emp.deptno%type

);

emp_record emp_record_type;

begin

select ename,sal,deptno into emp_record.names,emp_record.salary,emp_record.dno from emp where empno=&no;

dbms_output.put_line('names: ' || emp_record.names);

dbms_output.put_line('salary: ' || emp_record.salary);

dbms_output.put_line('dno: ' || emp_record.dno);

end;

---在insert的values子句中使用记录变量/记录成员,向dept表中插入一条数据set serveroutput on;

declare

dept_record dept%rowtype;

begin

dept_record.deptno :=&no;

dept_record.dname := &names;

dept_record.loc :=&city;

---insert into dept(deptno,dname,loc) values();

insert into dept values dept_record;

end;

2.嵌套表(nested table)

嵌套表一种用于处理PL/SQL数组的数据类型。嵌套表的元素下标从1开始,并且元素个数没有限制。

语法:

table type_name is table of element_type;

identifier type_name;

type_name指嵌套表的类型名。

element_type指嵌套表元素的数据类型。

identifier指嵌套表变量。

使用嵌套表元素时,需要先使用构造方法初始化嵌套表

declare

table emp_table_type is table of emp.ename%type;

emp_table emp_table_type := emp_table_type('c','c');

//emp表中雇员姓名set serveroutput on;

declare

type ename_table_type is table of emp.ename%type;

ename_table ename_table_type;

begin

ename_table :=ename_table_type('y1','y2');

select ename into ename_table(1) from emp where empno=&no;

dbms_output.put_line('employee name: ' || ename_table(1));

end;

3.集合方法

COUNT, DELETE, EXISTS, EXTEND, FIRST, LAST, LIMIT, NEXT, PRIOR, and TRIM

4.批量绑定

forall语法

forall index in lower_bound..upper_bound

sql_statement;

index隐含定义的×××变量(作为集合元素下标使用)

lower_bound|upper_bound集合元素的上界和下界。

create table tmp01(id number primary key, name varchar(10));

---codedeclare

type id_table_type is table of number index by binary_integer;

type name_table_type is table of varchar2(10) index by binary_integer;

id_table id_table_type ;

name_table name_table_type ;

start_time number;

end_time number;

begin

for i in 1..5000 loop

id_table(i):=i;

name_table(i):='name' || i;

end loop;

start_time := DBMS_UTILITY.GET_TIME;

forall i in 1..5000

insert into tmp01 values(id_table(i),name_table(i));

commit;

end_time := DBMS_UTILITY.GET_TIME;

dbms_output.put_line('total time is: ' || to_char((end_time-start_time)/100));

end;

5.索引表

---语法

TYPE type_name IS TABLE OF element_type [NOT NULL] INDEX BY key_type;

indentifer type_name;

type_name指定用户自定义数据类型名称

element_type 指定索引表元素的数据类型

key_type指定索引表元素下标的数据类型(varchar2,binary_integer,pls_integer等)

indentifer指定索引表变量

索引表的下标可以为负值,而且元素个数没有限制。

---codeset serveroutput on;

declare

type ename_table_type is table of emp.ename%type index by binary_integer;

ename_table ename_table_type;

begin

select ename into ename_table(1) from emp where empno=&no;

dbms_output.put_line('employee name : ' || ename_table(1));

end;

---索引表中使用varchar2set serveroutput on;

declare

type city_table_type is table of number index by varchar2(10);

city_table city_table_type;

begin

city_table('zhouzq') := 1;

city_table('lidd') := 2;

city_table('lijian') := 3;

dbms_output.put_line('the first element: ' || city_table.first);

dbms_output.put_line('the last element: ' || city_table.last);

end;

6.游标

使用显示游标包括定义游标,打开游标,提取游标和关闭游标。

(1)定义游标

CURSOR cursor_name IS  select_statement;

(2)打开游标

OPEN cursor_name;

(3)提取游标

---提取一行

FETCH cursor_name into var1,var2...;

---提取多行

FETCH cursor_name BULK COLLECT INTO collect1,collect2...[LIMIT rows];

---collect1用于指定接受游标的集合变量

(4)关闭游标

CLOSE cursor_name;

显示游标属性:%isopen,%found,%notfound,%rowcount

---显示游标中使用fetch...into

//提取雇员名,薪水set serveroutput on;

declare

cursor emp_cursor is select ename,sal from emp where deptno=10;

v_ename emp.ename%type;

v_salary emp.sal%type;

begin

open emp_cursor;

loop

fetch emp_cursor into v_ename,v_salary;

exit when emp_cursor%notfound;

dbms_output.put_line(v_ename || ' : ' || v_salary);

end loop;

end;

---显示游标中使用fetch...bulk collect into

###显示部门10的所有雇员名set serveroutput on;

declare

cursor ename_cursor is select ename from emp where deptno=10;

type ename_table_type is table of varchar2(10);

ename_table ename_table_type;

begin

open ename_cursor;

fetch ename_cursor bulk collect into ename_table;

for i in 1..ename_table.count loop

dbms_output.put_line(ename_table(i));

end loop;

close ename_cursor;

end;

---游标FOR循环

语法:

FOR record_name IN cursor_name loop

statement1;...

end loop;

cursor_name:已定义的游标名称

record_name:隐含定义的记录变量名

在执行循环体内容之前,oracle会隐含地打开游标,并且每循环一次提取一次数据,提取完所有数据后,会自动退出循环并隐含关闭游标。

---FOR循环游标set serveroutput on;

declare

cursor ename_cursor is select ename from emp;

begin

for cc_record in ename_cursor loop

dbms_output.put_line(ename_cursor%rowcount ||': ' || cc_record.ename);

end loop;

end;

---游标FOR循环中直接使用子查询set serveroutput on;

begin

for cc_record in (select ename from emp) loop

dbms_output.put_line( cc_record.ename);

end loop;

end;

oracle 的遍历语法,oracle pl/sql之pl/sql语法相关推荐

  1. Oracle入门(十四.1)之PL / SQL简介

    一.PL / SQL描述 程序语言扩展到SQL: •允许将基本程序逻辑和控制流与SQL语句组合在一起. •是Oracle专有编程语言. - 它只能用于Oracle数据库或工具. 二.程序语言扩展到SQ ...

  2. Oracle PL/SQL 编程手册(SQL大全)

    一.SQLPLUS 1引言 SQL命令 以下17个是作为语句开头的关键字: alterdroprevoke auditgrantrollback* commit*insert ...

  3. Oracle学习笔记(最重要的是PL/SQL编程)

    一:Oracle认证,与其它数据库比较,安装 Oracle安装会自动的生成sys用户和system用户: (1) sys用户是超级用户,具有最高权限,具有sysdba角色,有create databa ...

  4. ORACLE PL/SQL编程--PL/SQL块结构和组成元素

      本篇主要内容如下: 2.1   PL/SQL块 2.2   PL/SQL结构 2.3   标识符 2.4   PL/SQL 变量类型 2.4.1  变量类型 2.4.2  复合类型 2.4.2.1 ...

  5. Oracle SQL Loader的详细语法

    Oracle   SQL   Loader的详细语法 SQL*LOADER是ORACLE的数据加载工具,通常用来将操作系统文件迁移到ORACLE数据库中.SQL*LOADER是大型数据 仓库选择使用的 ...

  6. vs oracle带参数更新,Oracle vs PostgreSQL Develop(23) - PL(pg)sql(参数声明)

    Oracle和PostgreSQL都提供了内置的编程语言(PL/SQL vs PL/pgSQL),在输入输出参数的声明上有较大的不同,如输入参数中存在inout/out参数,Oracle的函数可以有返 ...

  7. oracle pl sql注意问题,Oracle PL/SQL编写PL/SQL代码的注意事项

    (1)几个值得注意的关键字(2)变量常量赋值注意: ---------------------------------------------------------------------[@mor ...

  8. ebs oracle pl sql开发_PL/SQL设置

    1.PL/SQL Developer记住登陆密码 再使用PL/SQL Developer时,为了工作方便希望PL/SQL Developer记住登录Oracle的用户名和密码: 设置方法:PL/SQL ...

  9. oracle与sqlserver差异,Oracle与SQLServer的SQL语法差异总结

    Oracle与SQL Server应用差异对比分析 Oracle 10g 项目 存储过程格式 存储过程名(参数列表) IS Begin ---存储过程内容 End 存储过程名; 备注 CREATE O ...

最新文章

  1. Android - 小的特点 - 使用最新版本ShareSDK手册分享(分享自己定义的接口)
  2. Centos升级php mysql
  3. bmob php支付,基于Bmob在小程序端实现一键支付
  4. CMake1:HelloWorld
  5. Websocket实现前后台通信,demo小测试
  6. Leetcode每日一题:24.swap-nodes-in-pairs(两两交换链表中的节点)
  7. 论文笔记--网络新闻图像中人脸标注技术的研究-2011
  8. 基于R语言绘制BBC风格图表
  9. 人工智能的Hello World!
  10. linux安装开发工具
  11. elasticjob接入方式和管理端使用
  12. 自动升级WordPress失败解决方法
  13. html js点击下拉菜单代码,JavaScript下拉菜单功能实例代码
  14. PTA 新浪微博热门话题 详细题解 附额外样例
  15. 基于IAAS和SAAS的运维自动化-张克琛
  16. 2018年第九届蓝桥杯省赛C/C++ A组(蒻鸡自己写的,看不上勿喷,自己的一点想法)
  17. 洛谷P5238 整数校验器【三月月赛】
  18. 数据库SQL实践25:获取员工其当前的薪水比其manager当前薪水还高的相关信息
  19. SOPC教学笔记01——绪论
  20. 因为一首歌,想念一个人?

热门文章

  1. 客户端支持的cookie
  2. SOA的缺陷及其与微服务的关系
  3. Servlet_生命周期方法
  4. Spring Boot整合Spring Data Redis-存取JSON格式Java对象
  5. mysql的索引介绍_2
  6. Bootstrap全局css样式_表单
  7. SpringBoot 上传多个文件
  8. 210221阶段三线程、信号量、互斥锁
  9. 200725学习日报循环语句和数组
  10. swift3 0 流控制