oracle 的遍历语法,oracle pl/sql之pl/sql语法
一.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语法相关推荐
- Oracle入门(十四.1)之PL / SQL简介
一.PL / SQL描述 程序语言扩展到SQL: •允许将基本程序逻辑和控制流与SQL语句组合在一起. •是Oracle专有编程语言. - 它只能用于Oracle数据库或工具. 二.程序语言扩展到SQ ...
- Oracle PL/SQL 编程手册(SQL大全)
一.SQLPLUS 1引言 SQL命令 以下17个是作为语句开头的关键字: alterdroprevoke auditgrantrollback* commit*insert ...
- Oracle学习笔记(最重要的是PL/SQL编程)
一:Oracle认证,与其它数据库比较,安装 Oracle安装会自动的生成sys用户和system用户: (1) sys用户是超级用户,具有最高权限,具有sysdba角色,有create databa ...
- 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 ...
- Oracle SQL Loader的详细语法
Oracle SQL Loader的详细语法 SQL*LOADER是ORACLE的数据加载工具,通常用来将操作系统文件迁移到ORACLE数据库中.SQL*LOADER是大型数据 仓库选择使用的 ...
- vs oracle带参数更新,Oracle vs PostgreSQL Develop(23) - PL(pg)sql(参数声明)
Oracle和PostgreSQL都提供了内置的编程语言(PL/SQL vs PL/pgSQL),在输入输出参数的声明上有较大的不同,如输入参数中存在inout/out参数,Oracle的函数可以有返 ...
- oracle pl sql注意问题,Oracle PL/SQL编写PL/SQL代码的注意事项
(1)几个值得注意的关键字(2)变量常量赋值注意: ---------------------------------------------------------------------[@mor ...
- ebs oracle pl sql开发_PL/SQL设置
1.PL/SQL Developer记住登陆密码 再使用PL/SQL Developer时,为了工作方便希望PL/SQL Developer记住登录Oracle的用户名和密码: 设置方法:PL/SQL ...
- oracle与sqlserver差异,Oracle与SQLServer的SQL语法差异总结
Oracle与SQL Server应用差异对比分析 Oracle 10g 项目 存储过程格式 存储过程名(参数列表) IS Begin ---存储过程内容 End 存储过程名; 备注 CREATE O ...
最新文章
- Android - 小的特点 - 使用最新版本ShareSDK手册分享(分享自己定义的接口)
- Centos升级php mysql
- bmob php支付,基于Bmob在小程序端实现一键支付
- CMake1:HelloWorld
- Websocket实现前后台通信,demo小测试
- Leetcode每日一题:24.swap-nodes-in-pairs(两两交换链表中的节点)
- 论文笔记--网络新闻图像中人脸标注技术的研究-2011
- 基于R语言绘制BBC风格图表
- 人工智能的Hello World!
- linux安装开发工具
- elasticjob接入方式和管理端使用
- 自动升级WordPress失败解决方法
- html js点击下拉菜单代码,JavaScript下拉菜单功能实例代码
- PTA 新浪微博热门话题 详细题解 附额外样例
- 基于IAAS和SAAS的运维自动化-张克琛
- 2018年第九届蓝桥杯省赛C/C++ A组(蒻鸡自己写的,看不上勿喷,自己的一点想法)
- 洛谷P5238 整数校验器【三月月赛】
- 数据库SQL实践25:获取员工其当前的薪水比其manager当前薪水还高的相关信息
- SOPC教学笔记01——绪论
- 因为一首歌,想念一个人?