存储过程与游标练习
Oralce PLSQL 存储过程 之 游标 实践!

声明:本文中的所有代码均是实战敲出来的!杜绝copy!代码是以游标的编写、调用、为目的。
从简单到复杂,用迭代的思想不断丰富例子功能。
希望对各位同学有所帮助。
------------单纯的一个声明,然后输入一个数,打印输出declare v_salemp.sal%type ;beginselect sal into v_sal from empwhere emp.empno=&no;dbms_output.put_line(v_sal||'Oralce存储过程实践!我是可以实现的!');end;-----------声明一个游标,遍历游标,处理游标的值/不输入参数的形式declarecursor v_sal_cursor isselect sal from emp ;var_salemp.sal%type;beginopen v_sal_cursor;loopfetch v_sal_cursor into var_sal ;exitwhen v_sal_cursor%notfound;dbms_output.put_line(var_sal ||'--------我就要成功了!!') ;dbms_output.put_line('当前游标状态:');endloop;close v_sal_cursor;end;----------声明一个游标,遍历游标,对话框输入一个参数,打印输出declarecursor v_sal_cursor isselect sal from emp where emp.empno=&no ;var_salemp.sal%type;beginopen v_sal_cursor;loopfetch v_sal_cursor into var_sal ;exitwhen v_sal_cursor%notfound;dbms_output.put_line(var_sal ||'--------我就要成功了!!') ;dbms_output.put_line('当前游标状态:');endloop;close v_sal_cursor;end;---------在这里没有用循环,所以只会取出一个结果,也就是一行记录declarecursor v_sal_cursor isselect emp.sal from emp ;var_salemp.sal%type;open v_sal_cursor;fetch v_sal_cursor into var_sal;if v_sal_cursor%foundthendbms_output.put_line('我是XXX,高级JAVA软件工程师!'|| var_sal); endif;close v_sal_cursor;end;-----用if else 判断语句,另外加上循环进行遍历的方法。
MySQL中的游标操作与存储过程使用方法

MySQL中的游标操作与存储过程使用方法引言对于开发者来说,数据操作是一个非常重要的任务。
在MySQL中,游标操作和存储过程是两个非常常见的功能,它们可以帮助我们更高效、更灵活地操作和管理数据。
本文将介绍MySQL中的游标操作和存储过程的使用方法,帮助读者更好地应用这些功能。
第一部分:游标操作什么是游标?游标是一种数据库对象,它用于处理数据集。
通过游标,我们可以逐行处理查询结果,而不是一次性地将所有结果返回。
这对于处理大量数据或者需要在结果集上进行逐行处理的情况非常有用。
游标的基本使用方法在MySQL中,使用DECLARE语句声明游标,使用FETCH语句获取游标的下一行数据,使用CLOSE语句关闭游标。
下面是一个简单的示例:```DECLARE cursor_name CURSOR FOR SELECT column1, column2 FROMtable_name;OPEN cursor_name;FETCH cursor_name INTO variable1, variable2;CLOSE cursor_name;```在这个示例中,我们首先声明了一个名为"cursor_name"的游标,然后打开游标并获取第一行数据到变量"variable1"和"variable2"中,最后关闭游标。
游标的类型MySQL支持两种类型的游标:FORWARD_ONLY和SCROLL。
FORWARD_ONLY游标只能向前遍历结果集,而SCROLL游标可以以任何顺序遍历结果集,包括向前、向后和随机访问。
使用游标实现分页查询游标非常适合实现分页查询功能。
通过游标,我们可以在一个较大的结果集中,按照一定的页大小逐页取出数据,而不需要一次性将所有数据加载到内存中。
下面是一个使用游标实现分页查询的示例:```DECLARE page_cursor SCROLL CURSOR FOR SELECT column1, column2 FROM table_name LIMIT start_index, page_size;OPEN page_cursor;FETCH page_cursor INTO variable1, variable2;WHILE NOT done DO-- 处理当前行数据...FETCH page_cursor INTO variable1, variable2;-- 判断是否还有下一页数据IF no_more_data THENSET done = TRUE;END IF;END WHILE;CLOSE page_cursor;```在这个示例中,我们使用了SCROLL游标,并通过LIMIT子句指定了查询的起始位置和页大小。
实验6 游标与存储过程

实验6:游标与存储过程6.1 实验目的与要求(1) 掌握游标的定义和使用方法。
(2) 掌握存储过程的定义、执行和调用方法。
(3) 掌握游标和存储过程的综合应用方法。
6.2 实验案例下面以简单实例介绍游标的具体用法。
[例6.1] 利用游标选取业务科员工的编号、姓名、性别、部门和薪水字段,并逐行显示游标中的信息。
DECLARE SCROLL cur_emp CURSOR FORSELECT employeeno, employeename, sex, department, salaryFROM employeeWHERE department='业务科'ORDER BY employeeno /*定义游标*/OPEN cur_emp /*打开游标*/SELECT 'CURSOR内数据条数'=@@cursor_rows /*显示游标内记录的个数*/FETCH NEXT FROM cur_emp /*逐行提取游标中的记录*/WHILE (@@FETCH_status<>-1) /*判断FETCH语句是否执行成功*/BEGINSELECT 'cursor读取状态'=@@FETCH_status/*显示游标的读取状态*/FETCH NEXT FROM cur_emp/*提取游标下一行信息*/ENDCLOSE cur_emp/*关闭游标*/DEALLOCATE cur_emp/*释放游标*/本例中,@@cursor_rows是返回连接上最后打开的游标中当前存在的合格行的数量。
具体参数信息见表6-1所示。
@@FETCH_status是返回被FETCH语句执行的最后,而不是任何当前被连接打开的游标的状态。
具体参数见表6-2所示。
表6-2 @@FETCH_status参数返回值的描述表[例6.2] 利用游标选取业务科员工的编号、姓名、性别、部门和薪水字段,并以格式化的方式输出游标中的信息。
SQL存储过程试题及答案

--写存储过程及调用存储过程/*1.写出创建分数存储过程用于计算某门课程成绩最高分、最低分、平均分,参数课程号。
*/--2.写出统计某门课选人数的存储过程,输入参数课程号,输出参数人数。
/*3.创建存储过程,要求根据学生姓名查看学生的籍贯.(要求:在存储过程里定义两个参数,第一个接收由调用程序指定的输入值(学生姓名),第二个参数用于将该值返回调用程序)*//*4.程序员工资表:ProWage字段名称数据类型说明ID int 自动编号,主键PName Char(10) 程序员姓名Wage int 工资创建一个存储过程,对程序员的工资进行分析,月薪1500到10000不等,如果有百分之五十的人薪水不到2000元,给所有人加薪,每次加100,再进行分析,直到有一半以上的人大于2000元为止,存储过程执行完后,最终加了多少钱?例如:如果有百分之五十的人薪水不到2000,给所有人加薪,每次加100元,直到有一半以上的人工资大于2000元,调用存储过程后的结果如图:请编写T-SQL来实现如下功能:查询是否有一半程序员的工资在2200、3000、3500、4000、5000或6000元之上,如果不到分别每次给每个程序员加薪100元,至之一半程序员的工资达到2200,3000,3500,4000,5000或6000元。
/*5.编写一个存储过程PR_GET_PASS_RA TE统计某门课程的及格率,其传入参数是课程号P_CNO,传出参数是该课程成绩的及格率P_PASSRATE,及格率的格式形如:86.56%。
6.创建触发器T_1,功能是当向数据表学生添加记录时,显示学生的信息。
create trigger T_1 on 学生after insertas select * from 学生insert into 学生values('3001','李四','男','计本10')7.创建触发器T_2,功能是当向数据表班级添加、修改和删除记录时,显示学生的信息。
oracle 存储过程 游标的写法

在 Oracle 数据库中,游标(Cursor)是用于从结果集中逐行检索数据的数据库对象。
下面是一个使用游标的基本存储过程的示例:sqlCREATE OR REPLACE PROCEDURE fetch_employee_data AS-- 声明游标CURSOR employee_cursor ISSELECT employee_id, first_name, last_name, salaryFROM employees;-- 声明变量来存储从游标中检索的数据v_employee_id employees.employee_id%TYPE;v_first_name employees.first_name%TYPE;v_last_name st_name%TYPE;v_salary employees.salary%TYPE;BEGIN-- 打开游标OPEN employee_cursor;-- 循环遍历游标中的每一行数据LOOP-- 从游标中检索数据到变量中FETCH employee_cursor INTO v_employee_id, v_first_name, v_last_name, v_salary;-- 退出循环如果游标中没有更多的数据EXIT WHEN employee_cursor%NOTFOUND;-- 在此处处理每一行数据,例如打印或执行其他操作DBMS_OUTPUT.PUT_LINE('Employee ID: ' || v_employee_id || ', Name: ' || v_first_name || ' ' || v_last_name || ', Salary: ' || v_salary);END LOOP;-- 关闭游标CLOSE employee_cursor;EXCEPTIONWHEN OTHERS THEN-- 处理异常情况,例如打印错误消息DBMS_OUTPUT.PUT_LINE('An error occurred: ' || SQLERRM);END fetch_employee_data;/上面的存储过程名为 fetch_employee_data,它声明了一个名为 employee_cursor 的游标,用于从 employees 表中检索员工的 ID、姓名和薪水。
MySql存储过程和游标的使用实例

MySql存储过程和游标的使⽤实例⽬录前⾔1.创建存储过程。
2.查看存储过程名称3.调⽤存储过程4.删除存储过程总结前⾔这⾥存储过程和游标的定义和作⽤就不介绍了,⽹上挺多的,只通过简单的介绍,然后⽤个案例让⼤家快速了解。
实例中会具体说明变量的定义,赋值,游标的使⽤,控制语句,循环语句的介绍。
1.创建存储过程。
CREATE PROCEDURE myproc(OUT s int)BEGINSELECT COUNT(*) INTO s FROM students;END存储过程根据需要可能会有输⼊、输出、输⼊输出参数,如果有多个参数⽤","分割开。
MySQL存储过程的参数⽤在存储过程的定义,共有三种参数类型,IN,OUT,INOUT:IN参数的值必须在调⽤存储过程时指定,在存储过程中修改该参数的值不能被返回,为默认值OUT:该值可在存储过程内部被改变,并可返回INOUT:调⽤时指定,并且可被改变和返回2.查看存储过程名称SELECT routine_name FROM information_schema.routines WHERE routine_schema='数据库名称';3.调⽤存储过程CALL myproc()4.删除存储过程DROP PROCEDURE IF EXISTS myproc;因为mysql中游标只能在存储过程和⽅法中使⽤,所以就直接通过案例介绍游标。
案例:该案例采⽤⽆参存储过程,有参的也挺简单,根据上⾯的介绍,对应实现就⾏,该存储过程主要就创建⼀个存储过程,⽤它做查询修改等操作。
#检查该存储过程是否存在存在就删除了再创建DROP PROCEDURE IF EXISTS processnames ;#创建存储过程CREATE PROCEDURE processnames()#BEGIN END 存储过程中的sql逻辑写在BEGIN 和END 中BEGIN#定义变量DECLARE var_name VARCHAR(300);DECLARE var_uuid VARCHAR(300);DECLARE count int DEFAULT 0 ;DECLARE i int DEFAULT 0 ;DECLARE done INT;#定义游标DECLARE nameCursor CURSOR FOR SELECT ParentId FROM datadictionary GROUP BY ParentId;#该sql语句作⽤是在你遍历游标的时候游标循环结束就会执⾏这句话,并给done赋值为1 然后循环就会停⽌但该语句不适⽤WHILE 循环语句。
MySQL视图存储过程练习题

一、编程题
创建数据库为: test_db
数据库中有以下表:
班级表(clazz)
学生表(student)
课程表(course)
选课表(selection)
操作题
1、创建一个视图,视图实现的是查询每个学生的年龄,性别。
2、创建一个视图,视图实现的是查询每个学生的姓名,所在的班级以及班
主任的姓名。
3、创建测试用户test,密码root。
并分配mysql数据库中的所有权限。
4、创建一个存储过程,用于查询课程表中所有信息。
并调用该存储过程。
5、创建一个存储过程,用于查询课程表中学分绩点在某个范围内的课程名
称,课程简介。
6、统计课程表中的课程数量,如果小于6插入两条课程信息,否则删除id
大于6课程信息。
7、创建存储过程,使用游标循环获取班级表中第3结果的班级名称,任
课老师的信息该存储过程。
8、创建存储过程,使用游标循环获取班级表中所有结果的班级名称。
并调用该存储过程。
(使用repeat循环方式)
9、创建存储过程,使用游标循环获取学生表中所有结果的学生姓名和年龄。
并调用该存储过程。
(使用while循环方式)。
存储过程游标有用

存储过程游标有⽤-- 语法/*create [or replace] procedure 存储过程名称(参数名1 in|out 数据类型,参数名2 in|out 数据类型,...) as|is-- 声明变量begin-- 过程化语句end;*/--- 根据员⼯编号得到员⼯的年薪create or replace procedure getYearSal(eno in number , yearsal out number)asbeginselect sal * 12 + nvl(comm,0) into yearsal from emp where empno = eno;end;-- 访问存储过程declareys number;begingetYearSal(7788, ys);dbms_output.put_line('年薪'||ys);end;--- 给某员⼯涨⼯资(打印涨前的⼯资和涨后的⼯资)create or replace procedure updateSal(eno in number ,psal in number)isoldsal number;newsal number;begin-- 打印涨前的⼯资select sal into oldsal from emp where empno = eno;dbms_output.put_line('涨前的⼯资:'||oldsal);-- 涨⼯资update emp set sal = sal + psal where empno = eno;commit;-- 打印涨后的⼯资select sal into newsal from emp where empno = eno;dbms_output.put_line('涨后的⼯资:'||newsal);end;-- 访问只有输⼊参数的存储过程call updateSal(7788,100);---- 举例:返回游标的存储过程-- 得到某部门所有的员⼯信息create or replace procedure getEmps(dno in number ,emps out sys_refcursor)asbegin-- 给动态的游标赋值open emps for select * from emp where deptno = dno;end;-- 访问带有输出参数为游标的存储过程declareemps sys_refcursor;prow emp%rowtype;begingetEmps(20, emps);loopfetch emps into prow;exit when emps%notfound;dbms_output.put_line(prow.empno||','||prow.ename);end loop;close emps;end;游标## 四、游标&例外```--- 游标(集合): ⽤来处理返回多⾏记录的问题-- select into 语句只能解决返回⼀⾏记录的问题declarepname emp.ename%type;beginselect ename into pname from emp where deptno = 40; dbms_output.put_line(pname);end;--- 声明游标-- cursor 游标名 is sql查询语句;-- 遍历游标的过程-- 打开游标-- 提取游标中的⼀⾏内容: fetch 游标名 into 变量名;-- 循环语句, exit when 游标名%notfound;-- 关闭游标-- 举例:使⽤游标打印20号部门的员⼯姓名和⼯作declarecursor cur is select ename ,job from emp where deptno = 20; pname emp.ename%type;pjob emp.job%type;begin-- 打开游标open cur;loopfetch cur into pname,pjob;-- 当游标中没有记录时退出exit when cur%notfound;dbms_output.put_line(pname || ','|| pjob);end loop;-- 关闭游标close cur;end;-- 举例-- 使⽤游标对20号部门的员⼯涨⼯资(100)-- 找出20号部门的员⼯编号,更新⼯资declarecursor cur is select empno from emp where deptno = 20; begin-- for 循环:⾃动打开,关闭游标for c in cur loopupdate emp set sal = sal + 100 where empno = c.empno; end loop;end;update emp set sal = sal +100 where deptno = 20;### ⼋、触发器```---- 触发器(监听器): 监听表中的数据是否发⽣了改变/*create or replace trigger 触发器名称before |after -- 改变之前执⾏触发器还是之后执⾏insert|update|deleteon 表 -- 修改的是哪⼀张表[触发器的级别:表级的触发器,⾏级触发器]declarebeginend;*/-- 举例:添加⼀条记录(打印添加了⼀条记录)create or replace trigger insertEmpafterinserton empdeclarebegindbms_output.put_line('添加了⼀条记录');end;insert into emp(empno ,ename) values(1002,'zhangfei');-- 不能给员⼯降薪create or replace trigger notUpdateLowerSalbeforeupdateon empfor each row -- ⾏级的触发器:只要使⽤new,old 就必须使⽤⾏级触发器declarebeginif :new.sal < :old.sal then-- raise_application_error(p1,p2)-- p1 : 错误的编号:- 20001 ~ -20999-- p2 :错误的信息raise_application_error(-20001 , '不能给员⼯降薪');end if;end;update emp set sal = sal - 1 where empno = 7788;-- 使⽤触发器来模拟mysql中⾃增的效果create sequence tseq;create or replace trigger autoIncrementbeforeinserton empfor each rowdeclarebeginselect tseq.nextval into :new.empno from dual;end;insert into emp(empno,ename) values(100,'lisi');select * from emp;```。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
创建三个表:学生(学号,姓名)、课程(课程号,课程名)、成绩(学号、课程号、分数),然后在三个表中分别添加记录。
按照输入的课程名称打印此门课程的成绩报表(如不给定课程名称则打印SQL课程的成绩),输出结果按照分数降序排列:
例如:
《SQL》成绩表
****************************************************
名次学号姓名成绩
1 0508044126 李军95
2 0508044124 李明85
3 0508044125 王刚75
****************************************************
*/
use pubs
IF EXISTS (SELECT NAME FROM sysobjects
WHERE NAME = '学生')
DROP table 学生
GO
IF EXISTS (SELECT NAME FROM sysobjects
WHERE NAME = '课程')
DROP table 课程
GO
IF EXISTS (SELECT NAME FROM sysobjects
WHERE NAME = '成绩')
DROP table 成绩
GO
create table 学生(学号char(10) primary key
constraint xh_chk check (学号like '0508044[1-4][0-3][0-9]'),姓名nvarchar(10) not null) create table 课程(课程号char(6) primary key,课程名称nvarchar(40))
create table 成绩(学号char(10) not null,课程号char(6) not null,分数numeric(4,1))
insert 学生values('0508044124','李明')
insert 学生values('0508044125','王刚')
insert 学生values('0508044126','李军')
insert 课程values('080101','SQL')
insert 课程values('080204','D S')
insert 成绩values('0508044124','080101',85)
insert 成绩values('0508044124','080204',95)
insert 成绩values('0508044125','080101',75)
insert 成绩values('0508044125','080204',86)
insert 成绩values('0508044126','080101',95)
go
if exists(select * from sysobjects where name='cj_proc' and xtype='p')
drop proc cj_proc
GO
create proc cj_proc @KCM nvarchar(40)=’SQL’
as
SET NOCOUNT ON
DECLARE @XH char(10),@XM nvarchar(10),@kch nvarchar(6),
@CJ numeric(4,1),@message nvarchar(80),@mc int
if not exists(select 课程.课程号from 课程inner join 成绩on 课程.课程号=成绩.课程号and 课程.课程名称=@kcm)
print '无此课程成绩'
else
begin
select @kch=课程.课程号from 课程where 课程.课程名称=@kcm
print ' 《'+@kcm+'》成绩表'
print REPLICATE('*',48)
print '名次学号姓名成绩'
declare xhcj_cursor cursor scroll
for select 学生.学号,姓名,分数from 学生,成绩
where 成绩.学号=学生.学号and 课程号=@kch
order by 分数desc
open xhcj_cursor
fetch next from xhcj_cursor into @xh,@xm,@cj
set @mc=1
while @@fetch_status=0
begin
set
@message=ltrim(str(@mc))+space(10)+@xh+space(7)+@xm+space(12)+ltrim(str(@CJ)) PRINT @message
fetch next from xhcj_cursor into @xh,@xm,@CJ
set @mc=@mc+1
end
print REPLICATE('*',48)
CLOSE xhcj_cursor
DEALLOCATE xhcj_cursor
end
go。