Oracle游标变量、存储过程、包、函数
PLSQL常用功能设置
PLSQL常用功能设置PL/SQL(Procedural Language/Structured Query Language)是Oracle数据库的扩展语言,它提供了一种在数据库中编写存储过程、触发器、函数等可执行代码的方式。
PL/SQL具有很多功能和特性,下面是一些常用的功能设置:1. 变量声明和赋值:在PL/SQL中,可以声明各种类型的变量,并且可以对变量进行赋值。
例如,可以声明一个整型变量并将其赋值为10:`v_number NUMBER := 10;`2. 条件语句:PL/SQL支持if-else语句和case语句来处理条件逻辑。
if-else语句用于判断条件是否成立并执行相应的代码块,case语句用于根据不同的条件执行不同的代码块。
3. 循环语句:PL/SQL提供了几种循环结构,例如,可以使用for循环、while循环和loop循环来重复执行一段代码。
这些循环结构可以根据条件来决定是否继续执行。
4.异常处理:PL/SQL支持异常处理机制,可以在代码中处理错误和异常。
可以使用异常处理块来捕获和处理各种类型的异常,并采取相应的措施。
常见的异常类型包括NO_DATA_FOUND、TOO_MANY_ROWS和OTHERS等。
5.存储过程:PL/SQL允许在数据库中创建存储过程。
存储过程是一段可执行的代码,可以在需要时被调用。
存储过程可以接收输入参数,在执行过程中进行业务逻辑处理,并返回结果。
6.触发器:PL/SQL还支持在数据库中创建触发器。
触发器是一种特殊的存储过程,它与数据库中的表相关联,并在表上的特定事件发生时自动执行。
触发器可以在插入、更新或删除数据时执行特定操作。
7.函数:PL/SQL支持创建函数。
函数是一种可重用的代码块,可以接收输入参数,并返回一个结果。
函数可以在查询中使用,也可以像存储过程一样在其他存储过程或传递中调用。
8.游标:PL/SQL中的游标用于在数据库中检索和处理多行结果集。
oracle存储过程介绍
存储过程优点(2)
4)重复使用。存储过程可以重复使用,从而可以减少数 据库开发人员的工作量。 5)灵活:使用存储过程,可以实现存储过程设计和编码 工作分开进行,只要将存储过程名、参数、及返回信 息告诉编码人员即可。
存储过程缺点(1)
1)移植性差:使用存储过程封装业务逻辑将限制应用程 序的可移植性; 2)维护成本高:如果更改存储过程的参数或者其返回的 数据及类型的话,需要修改应用程序的相关代码,比 较繁琐。
执行存储过程
执行存储过程语法: ,...]);
CALL/PERFORM Procedure 过程名([参数1,参数2
在PL/SQL中,数据库服务器支持在过程体中调用其他 存储过程 使用CALL或者PERFORM等方式激活存储过程的执行。 调用时”()”是不可少的,无论是有参数还是无参数。
过程名:数据库服务器合法的对象标识 参数列表:用名字来标识调用时给出的参数值,必须 指定值的数据类型。参数也可以定义输入参数、输出 参数或输入/输出参数。默认为输入参数。 过程体:是一个<PL/SQL块>。包括声明部分和可执 行语句部分 ;不用 declare 语句
创建存储过程(2)
例子: [例1] 利用存储过程来实现下面的应用: 从一个账户转指定数额的款项到 另一个账户中。 CREATE PROCEDURE TRANSFER(inAccount INT, outAccount INT , amount FLOAT) AS totalDeposit FLOAT; BEGIN /* 检查转出账户的余额 */ SELECT total INTO totalDeposit FROM ACCOUNT WHERE ACCOUNTNUM=outAccount; IF totalDeposit IS NULL THEN /* 账户不存在或账户中没有存款 */ ROLLBACK; RETURN; END IF;
oracle declare的用法
oracle declare的用法在Oracle中,DECLARE语句用于定义变量、游标或子程序。
DECLARE语句可以用于存储过程、函数、触发器和包中,用于定义这些程序中使用的变量或游标。
DECLARE语句的语法格式如下:sqlCopy codeDECLAREvariable_name1 [CONSTANT | TYPE] [NOT NULL] [:= | DEFAULT] value1;variable_name2 [CONSTANT | TYPE] [NOT NULL] [:= | DEFAULT] value2;...BEGIN--可执行的PL/SQL代码END;在DECLARE语句中,可以声明多个变量或游标,每个变量或游标都需要指定变量名称,变量类型(可以是简单类型、复合类型或对象类型)、是否为常量、是否为空、默认值等。
在DECLARE语句中,还可以定义存储过程、函数、触发器和包等程序,这些程序可以包含一个或多个变量和游标。
在这些程序中,DECLARE语句用于定义变量和游标的类型和属性,并在BEGIN-END块中编写具体的程序代码。
以下是一个简单的示例,演示如何使用DECLARE语句定义变量:scssCopy codeDECLAREmessage VARCHAR2(20) := 'Hello World!';BEGINDBMS_OUTPUT.PUT_LINE(message);END;在上面的示例中,定义了一个名为message的VARCHAR2类型变量,值为'Hello World!',并使用DBMS_OUTPUT.PUT_LINE输出该变量的值。
该程序将输出'Hello World!'。
需要注意的是,DECLARE语句只能在存储过程、函数、触发器和包等程序中使用,而不能单独使用。
在程序中定义的变量或游标仅在该程序内部有效,不能在其他程序中使用。
Oracle存储过程--游标循环调用函数存储过程
Oracle存储过程--游标循环调⽤函数存储过程存储过程的基本语法如下:create or replace procedure procedure_nameasbeginextention;end;在sqlplus中调⽤存储过程的⽅式:beginprocedure_name;end;我的业务需求是:查询⾃2015年1⽉1号以来的,每天的总订单量(截⽌到当天的所有订单),我需要接收⼀个时间,使订单时间⼩于等于该时间,然后对订单数计数,⼤概就是这样;这是⼀个需要运⾏的存储过程:CREATE OR REPLACEprocedure "RECYCLE_EVERY_DAY"ISbegindeclare--定义⼀个游标变量 ,将参数集合存进游标中cursor every_day_list isSELECTTO_DATE( '2015-01-01', 'yyyy-MM-dd' ) + ROWNUM - 1 AS daylistFROMDUAL CONNECT BY ROWNUM <= trunc(SYSDATE - to_date( '2015-01-01', 'yyyy-MM-dd' )) + 1 ;--这个SQL是求出2015年1⽉1号⾄今为⽌的每⼀天的⼀个时间结果集begin--循环游标,取出游标中的每⼀个值,然后将值传⼊到你需要的地⽅,⽐如另外⼀个存储过程for item in every_day_list LOOP-- DBMS_OUTPUT.PUT_LINE(item.daylist); --打印出游标中的每⼀项ADD_DATE_TEST(item.daylist);--ADD_DATE_TEST(item.daylist)是我的另外⼀个存储过程end loop;end;end RECYCLE_EVERY_DAY;下⾯是我的需要参数的存储过程:CREATE OR REPLACEPROCEDURE "ADD_DATE_TEST"(VS_DATE IN DATE) ISBEGINDECLARE cursorORDER_TYPE_LIST is --声明游标,将查询结果集存⼊游标SELECT DISTINCTto_char( VS_DATE, 'yyyy' ) AS year,CUSTOMER_TYPE,COUNT(*) AS ORDER_NUMS,SUM(COUNT(*)) over() AS ALL_ORDERSFROMT_ORDER_LISTWHERETO_CHAR(join_time,'yyyy-MM-dd') <= TO_CHAR(VS_DATE,'yyyy-MM-dd')GROUP BY to_char( VS_DATE, 'yyyy' ), CUSTOMER_TYPE ;beginFOR Itme in ORDER_TYPE_LIST LOOP --循环取出插⼊到相应的表insert into ZT_FWDX_TB_NUMTONGBI_XRD (ID,YEAR,CUSTOMER_TYPE,ORDER_NUMS,SUM_NUM,CREATE_TIME,IS_HISTORY,DATE_MONTH,DATE_DAY)values(SEQ_ZT_FWDX_NUMTONGBI_XRD.Nextval,Itme.year,Itme.KEHU_TYPE,Itme.ORDER_NUMS,Itme.ALL_ORDERS,VS_DATE,0,TO_CHAR(VS_DATE,'MM'),TO_CHAR(VS_DATE,'dd')); end loop;/*dbms_output.put_line(VS_DATE);*/--可以先试着打印出传⼊的参数,看是否是需要的参数end;COMMIT;--提交事务END ADD_DATE_TEST;⾥⾯的表和字段,可以换成⾃⼰需要的,忽略我⾃⼰的表信息;希望对你有帮助,有问题留⾔讨论!。
plsql 使用技巧
plsql 使用技巧PL/SQL是Oracle数据库中的一种编程语言,它结合了SQL语句和过程性编程语言的特点,提供了一种强大的数据库开发工具。
下面是一些PL/SQL使用技巧:1. 使用块:块是PL/SQL程序的基本单元。
使用块可以将一组相关的语句组织在一起,并提供一些错误处理机制。
块通常用于存储过程、触发器和函数中。
2. 使用游标:游标是用于在PL/SQL程序中处理查询结果的一种机制。
使用游标可以逐行处理查询结果,提供更灵活的数据操作方式。
3. 使用异常处理:异常处理是一种处理程序运行过程中出现异常的机制。
在PL/SQL中,可以使用EXCEPTION块来处理异常情况,提高程序的稳定性。
4. 使用存储过程和函数:存储过程和函数是一种将一组SQL语句和过程性语句组织在一起的机制。
使用存储过程和函数可以将复杂的逻辑封装起来,提高程序的可维护性和重用性。
5. 使用触发器:触发器是在数据库表中定义的一种特殊类型的存储过程。
使用触发器可以根据数据库表中的数据变化触发特定的逻辑处理。
6. 使用PL/SQL调试器:PL/SQL调试器是一种用于调试PL/SQL程序的工具。
使用调试器可以逐步执行PL/SQL代码,并查看变量的值和程序执行的状态,方便程序的调试和排错。
7. 使用PL/SQL包:PL/SQL包是将相关的存储过程、函数和变量组织在一起的一种机制。
使用包可以提供更好的模块化和封装性,方便程序的管理和维护。
8. 使用PL/SQL游标变量:PL/SQL游标变量是一种特殊的变量类型,用于在程序中保存游标的状态。
使用游标变量可以提高游标的灵活性和可重用性。
9. 使用PL/SQL集合类型:PL/SQL提供了各种集合类型,如数组、表和记录。
使用集合类型可以方便地处理多个数据元素,提高程序的性能和可读性。
10. 使用PL/SQL优化技巧:在编写和调试PL/SQL程序时,可以使用一些优化技巧来提高程序的性能。
例如,使用合适的索引、批量操作和合理的逻辑结构等。
oracle存储过程游标的用法
【主题】Oracle存储过程游标的用法在数据库管理和开发中,Oracle存储过程是一种非常常见的数据库对象,它允许我们在数据库中完成一系列操作,并且可以通过参数传递数据。
而游标则是存储过程中经常使用的数据库对象,用于处理查询结果集。
今天,我们将深入探讨Oracle存储过程中游标的用法,以便更好地理解和应用这一特性。
一、基本概念1.1 游标的定义和作用在Oracle数据库中,游标是一种用于处理查询结果集的对象。
它可以让存储过程逐行处理查询结果,进行逻辑判断和数据操作,从而实现更灵活的数据处理和业务逻辑。
在存储过程中,经常需要用到游标来处理复杂的查询逻辑和结果集操作。
1.2 游标的分类在Oracle数据库中,我们通常可以将游标分为显式游标和隐式游标。
显式游标是由程序员手动定义和使用的游标,而隐式游标则是在某些情况下自动创建和使用的游标。
两者在特性和使用方式上略有不同,需要根据实际情况选择合适的方式来处理查询结果集。
二、使用方式2.1 游标的声明和打开在存储过程中,我们需要先声明一个游标变量,然后通过OPEN语句打开游标,使其准备好处理查询结果集。
在声明游标时,需要指定游标的返回类型(REF CURSOR)和查询语句,以便游标知道如何处理结果集。
2.2 游标的循环和操作一旦游标被打开,我们就可以通过FETCH语句从游标中逐行读取数据,并对数据进行逻辑判断和操作。
通常我们会使用循环语句(如WHILE 循环或FOR循环)来逐行处理结果集,直到处理完所有数据为止。
2.3 游标的关闭和释放在完成游标的操作后,我们需要通过CLOSE语句关闭游标,以确保游标所占用的资源得到释放和回收,避免对系统性能造成不必要的影响。
游标关闭后,也需要及时释放游标变量所占用的资源,以免出现资源泄露和内存溢出的情况。
三、个人观点和理解通过对Oracle存储过程游标的用法进行深入探讨,我对游标的作用和使用方式有了更清晰的认识。
游标在存储过程中的灵活运用,可以帮助我们更好地处理复杂的查询结果集,实现精细化的数据逻辑和业务操作。
第5章_Oracle PL SQL语言及编程--包、触发器、同义词、序列
O r a c l e 数 据 库 与 应 用
删除包体和删除包 举例
例: DROP PACKAGE BODY EXPP; SELECT NAME FROM USER_SOURCE WHERE TYPE=‘PACKAGE’; --找到包EXPP DROP PACKAGE EXPP; --删除包EXPP
数据库管理
数据库应用
O r a c l e 数 据 库 与 应 用
本章学习要点
(1)PL/SQL的程序结构 (2) PL/SQL的字符集、标识符
(3) 数据类型、常量和变量
(4)结构控制语句 (5)游标的概念和使用 (6)过程的创建、调用和删除 (7)函数的创建、调用和删除 (8)包、触发器、同义词、序列的创建和使用
O r a c l e 数 据 库 与 应 用
5.6.2 创建触发器
触发器创建(权限:CREATE [ANY] TRIGGER),简化语法如下: CREATE [OR REPLACE] TRIGGER 触发器名 { BEFORE | AFTER } {INSERT | DELETE | UPDATE [OF column [, column …]]} [OR {INSERT | DELETE | UPDATE [OF column [, column …]]}...] ON [schema.]表名| [schema.]视图 [FOR EACH ROW ] [WHEN condition] PL/SQL块 | CALL procedure_name;
第5章 Oracle PL/SQL语言及编程
本章 学习导航
闪回技术 Oracle 11g 安装与配置 数 据 库 应 用 程 序 开 发
高级管理
数据库备份与恢复 数据库存储管理 数据库安全管理 PL/SQL编程基础 视图和索引操作
oracle包
1、包头
程序包由两个部分组成:包头与包体。
包头又可以称为包规范,用于规定程序包中可以容纳的存储过程、自定义函数、游标等PL/SQL元素。
包体则用于编写包头中规定的PL/SQL块元素实现代码。
创建包时,包体的名称必须与包头的名称相同,这样Oracle就可以通过相同的名称将包头与包体组织到一起。
创建包
可以使用OR REPLACE关键字将原先的定义覆盖。
(2)pl_statement:用于规定包中存放的内容,如果是PL/SQL块子程序,这是声明该子程序
在包头中可以声明变量,游标,子程序等内容,下面通过一个示例来演示包头的定义,示例说明:创建一个名为pack_emp的包头,分别在包头中创建一个根据员工编号获取员工姓名的函数与根据职位和部门编号获取员工信息的存储过
2、包体
程序包中的包体主要用于实现包头中声明的PL/SQL块元素,只有包头编译成功后,包体才能编译。
在包头中声明的对象可以直接在包体中使用,包体的名称必须与包头相同。
此外包体中实现的存储过程、自定义函数等子程序必须要与
可以使用OR REPLACE关键字将原先的定义覆盖。
(2)pl_body:包体中的主体代码,用于实现包头中定义的存储过程、自定义函数等PL/SQL块子程序。
包头与包体一定要一一对应,并且先要有包头,才能有包体。
下面通过一个示例来演示包体的创建,示例说明:创建pack_emp的包体,实现包中的存储过程与自定义函数。
3、调用包里面的内容。
oracle存储过程返回结果集的方法
oracle存储过程返回结果集的方法标题:Oracle存储过程返回结果集的方法摘要:在Oracle数据库中,存储过程是一种强大的特性,用于执行一系列的数据库操作。
本文将介绍如何在Oracle存储过程中返回结果集的方法,包括使用游标、临时表和函数等方式,以及它们的优缺点。
一、使用游标返回结果集1. 定义游标:在存储过程中,可以使用游标来返回结果集。
首先需要声明一个游标变量,并为其提供一个SELECT语句,该SELECT 语句用于生成结果集。
2. 打开游标:在定义游标后,需要使用OPEN语句来打开游标,这样才能开始获取结果集中的数据。
3. 获取数据:通过使用FETCH语句可以逐行获取结果集中的数据,并将其存储到合适的变量中。
可以使用循环控制结构来遍历整个结果集。
4. 关闭游标:在完成结果集的遍历后,需要使用CLOSE语句关闭游标,以释放系统资源。
优点:使用游标返回结果集的方法比较简单直观,适用于结果集较小的情况。
缺点:当结果集较大时,使用游标返回可能会导致性能问题。
二、使用临时表返回结果集1. 创建临时表:在存储过程中,可以创建一个临时表,用于存储结果集中的数据。
临时表可以通过CREATE GLOBAL TEMPORARY TABLE语句来创建,并在存储过程中使用INSERT INTO语句将结果集中的数据插入到临时表中。
2. 查询临时表:在存储过程中,可以使用SELECT语句查询临时表,获取结果集中的数据。
可以使用循环控制结构来遍历整个结果集。
3. 删除临时表:在完成结果集的使用后,需要使用DROP TABLE语句删除临时表,以释放系统资源。
优点:使用临时表返回结果集的方法比较灵活,适用于结果集较大的情况。
缺点:需要额外的空间来存储临时表,比较消耗系统资源。
三、使用函数返回结果集1. 创建函数:在存储过程中,可以创建一个函数,用于返回结果集。
函数可以通过CREATE FUNCTION语句来创建,并在存储过程中使用SELECT语句从函数中获取结果集。
2020年(Oracle管理)游标和异常处理 oracle
(Oracle管理)游标和异常处理oracle游标和异常处理游标的概念游标是SQL的一个内存工作区,由系统或用户以变量的形式定义。
游标的作用就是用于临时存储从数据库中提取的数据块。
在某些情况下,需要把数据从存放在磁盘的表中调到计算机内存中进行处理,最后将处理结果显示出来或最终写回数据库。
这样数据处理的速度才会提高,否则频繁的磁盘数据交换会降低效率。
游标有两种类型:显式游标和隐式游标。
在前述程序中用到的SELECT...INTO...查询语句,一次只能从数据库中提取一行数据,对于这种形式的查询和DML操作,系统都会使用一个隐式游标。
但是如果要提取多行数据,就要由程序员定义一个显式游标,并通过与游标有关的语句进行处理。
显式游标对应一个返回结果为多行多列的SELECT语句。
游标一旦打开,数据就从数据库中传送到游标变量中,然后应用程序再从游标变量中分解出需要的数据,并进行处理。
隐式游标如前所述,DML操作和单行SELECT语句会使用隐式游标,它们是:*插入操作:INSERT。
*更新操作:UPDATE。
*删除操作:DELETE。
*单行查询操作:SELECT...INTO...。
当系统使用一个隐式游标时,可以通过隐式游标的属性来了解操作的状态和结果,进而控制程序的流程。
隐式游标可以使用名字SQL来访问,但要注意,通过SQL游标名总是只能访问前一个DML操作或单行SELECT操作的游标属性。
所以通常在刚刚执行完操作之后,立即使用SQL游标名来访问属性。
游标的属性有四种,如下表所示。
范例:使用隐式游标的属性,判断对雇员工资的修改是否成功。
说明:本例中,通过SQL%FOUND属性判断修改是否成功,并给出相应信息。
显式游标游标的定义和操作游标的使用分成以下4个步骤。
1.声明游标在DECLEAR部分按以下格式声明游标:参数是可选部分,所定义的参数可以出现在SELECT语句的WHERE子句中。
如果定义了参数,则必须在打开游标时传递相应的实际参数。
oracle pl相关用法
oracle pl相关用法Oracle PL/SQL是一种过程化的SQL,允许在Oracle数据库中进行存储过程、函数和触发器的编写。
以下是Oracle PL/SQL的一些基本用法:1. 声明变量:在PL/SQL块中,使用DECLARE语句声明变量。
例如:```sqlDECLAREemp_id NUMBER(5);emp_name VARCHAR2(50);BEGIN-- 执行逻辑END;```2. 条件语句:使用IF语句进行条件判断。
例如:```sqlIF condition THEN-- 执行逻辑END IF;```3. 循环语句:使用LOOP、WHILE和FOR循环来重复执行代码块。
例如:```sqlLOOP-- 执行逻辑EXIT WHEN condition; -- 退出循环的条件END LOOP;```4. 游标:用于从查询结果中检索数据。
例如:```sqlDECLAREemp_id NUMBER(5);emp_name VARCHAR2(50);CURSOR emp_cur IS SELECT id, name FROM employees;BEGINOPEN emp_cur;LOOPFETCH emp_cur INTO emp_id, emp_name;EXIT WHEN emp_cur%NOTFOUND;-- 执行逻辑,例如输出数据DBMS__LINE(emp_id ', ' emp_name);END LOOP;CLOSE emp_cur;END;```5. 异常处理:使用DECLARE和BEGIN块来处理异常。
例如:```sqlDECLAREBEGIN-- 执行逻辑,可能会抛出异常EXCEPTIONWHEN exception_name THEN-- 处理异常的逻辑END;```。
Oracle数据库学习总结
Oracle数据库学习总结时间过的还真快,不知不觉中就在这里呆了半个月了。
这段时间里都在学习oracle数据库的编程,毕竟这是家软件外包公司。
像我们这样的新员工也就只能接触到些CURD的操作。
废话不多说,赶紧来梳理下这半月来学习的知识点.在来公司之前一直都是使用Sql Server数据库,用Sql Server也开发了3个小型项目。
所以对Sql语句以及在数据库中扮演重要作用的存储过程,触发器,视图,主键/外键约束都很熟。
但Oracle是一个全新的环境,记得刚装上Oracle 的时候,我都不知道在哪查看自己已经建立好的表格。
还好有师傅的帮忙,要不然我还真没这么快就能入门Oracle。
学习东西就要学习些能改变自己思维的东西,只有这样才能让自己的眼光比别人更独到,思维比别人更深邃,Oracle就是这样的东西。
当然做这样的事是要很大的驱动力的呀,如果公司不是都采用Oracle来写程序的话,我估计也就懒得学啦。
对于一位程序员来说并不需要完全掌握Oracle的所有知识,毕竟自己不是DBA。
在日常开发中也用不到那些命令和工具,但是有些知识点我们还是必须得熟练的掌握它们。
比如:一些基本的DDL和DML语句,存储过程,函数,视图,触发器,序列,游标,自定义类型和包。
下面我就把这段时间里学习Oracle获得的知识点罗列出来,一是为了方便以后查阅,二是为了和搭档交流学习经验。
要适应的一些细节从Sql Server转到Oracle进行数据库编程,第一道门槛就是语法问题。
很多很多的问题都是因为语法而产生的,现将它们统统集合起来并将它们一网打尽之。
PL结构。
在Sql Server中,采用的是批处理执行任务的方式,所以可以将多条sql语句选中批量执行,而不用顾忌要在专门的地方声明变量,在专门的地方进行逻辑编码。
在Oracle中采用的是PL编程方式,必须在专门的地方声明变循环结构,要达到循环在Oracle中有3种方式,各有各的好处,你懂的。
Oracle 数据库游标使用大全
Oracl e 游标使用大全目录Oracle 游标使用大全 (1)1.游标简介 (2)2.查询SELECT... INTO (2)3.%TYPE属性 (2)4.其他DML语句 (3)5.DML语句的结果 (3)5.1 SQL%FOUND和SQL%NOTFOUND (3)5.2SQL%ROWCOUNT (4)5.3SQL%ISOPEN (4)6.事务控制语句 (4)7.显式游标与隐式游标 (4)8.使用游标 (7)8.1 声明游标 (7)8.2 打开游标 (7)8.3 关闭游标 (7)8.4 从游标提取数据 (8)8.5 记录变量 (9)8.6 带参数的游标 (9)8.7 游标FOR循环 (11)8.8 在游标FOR循环中使用查询 (12)8.9 游标中的子查询 (12)8.10 游标中的更新和删除 (12)1. 游标简介在数据库中,游标是一个十分重要的概念,游标提供了一种灵活手段,可以对表中检索出的数据进行操作。
就本质而言,游标实际上是一种能从包括多条数据记录的结果集中每次提取一条记录的机制。
游标由结果集和结果集中指向特定记录的游标位置组成,游标充当指针的作用。
尽管游标能够遍历查询结果中的所有行,但它一次只能指向一行。
使用数据游标可以选择一组数据,可以在记录集上滚动游标,并检查游标指向的每一行数据。
可以用局部变量和游标的组合来分别检查每个记录,并在转移到下一个记录之前,进行所需的任何外部操作。
游标的另一个常见用途是保存查询结果,以便以后使用。
游标的结果集是由select语句产生,如果处理过程需要重复使用一个记录集,那么创建一次游标而重复使用若干次,比重复查询数据库要快得多。
2. 查询SELECT… INTO …在存储过程中,select某一字段时,后面必须紧跟into,如果select整个记录,利用游标的话就另当别论了。
SELECT语句用于从数据库中查询数据,当在PL/SQL中使用SELECT语句时,要与INTO子句一起使用,查询的返回值被赋予INTO子句中的变量,变量的声明是在DELCAREPL/SQL中SELECT语句只返回一行数据。
ORACLE_PLSQL存储过程教程
(1)SEQNAME.NEXTV AL里面的值如何读出来?可以直接在insert into test values(SEQNAME.NEXTV AL) 是可以用这样:SELECT tmp#_seq.NEXTV ALINTO id_tempFROM DUAL; 然后可以用id_temp(2)PLS-00103: 出现符号">"在需要下列之一时:代码如下:IF (sum>0)THENbeginINSERT INTO emesp.tp_sn_production_logV ALUES (r_serial_number, , id_temp);EXIT;end;一直报sum>0 这是个很郁闷的问题因为变量用了sum 所以不行,后改为i_sum>0(3)oracle 语法1. Oracle应用编辑方法概览答:1) Pro*C/C++/... : C语言和数据库打交道的方法,比OCI更常用;2) ODBC3) OCI: C语言和数据库打交道的方法,和ProC很相似,更底层,很少用;4) SQLJ: 很新的一种用Java访问Oracle数据库的方法,会的人不多;5) JDBC6) PL/SQL: 存储在数据内运行, 其他方法为在数据库外对数据库访问;2. PL/SQL答:1) PL/SQL(Procedual language/SQL)是在标准SQL的基础上增加了过程化处理的语言;2) Oracle客户端工具访问Oracle服务器的操作语言;3) Oracle对SQL的扩充;4. PL/SQL的优缺点答:优点:1) 结构化模块化编程,不是面向对象;2) 良好的可移植性(不管Oracle运行在何种操作系统);3) 良好的可维护性(编译通过后存储在数据库里);4) 提升系统性能;第二章PL/SQL程序结构1. PL/SQL块答:1) 申明部分, DECLARE(不可少);2) 执行部分, BEGIN...END;3) 异常处理,EXCEPTION(可以没有);2. PL/SQL开发环境答:可以运用任何纯文本的编辑器编辑,例如:VI ;toad很好用3. PL/SQL字符集答:PL/SQL对大小写不敏感4. 标识符命名规则答:1) 字母开头;2) 后跟任意的非空格字符、数字、货币符号、下划线、或# ;3) 最大长度为30个字符(八个字符左右最合适);5. 变量声明答:语法V ar_name type [CONSTANT][NOT NULL][:=value];注:1) 申明时可以有默认值也可以没有;2) 如有[CONSTANT][NOT NULL], 变量一定要有一个初始值;3) 赋值语句为“:=”;4) 变量可以认为是数据库里一个字段;5) 规定没有初始化的变量为NULL;第三章1. 数据类型答:1) 标量型:数字型、字符型、布尔型、日期型;2) 组合型:RECORD(常用)、TABLE(常用)、V ARRAY(较少用)3) 参考型:REF CURSOR(游标)、REF object_type4) LOB(Large Object)2. %TYPE答:变量具有与数据库的表中某一字段相同的类型例:v_FirstName studengts.first_name%TYPE;3. RECORD类型答:TYPE record_name IS RECORD( /*其中TYPE,IS,RECORD为关键字,record_name 为变量名称*/field1 type [NOT NULL][:=expr1], /*每个等价的成员间用逗号分隔*/field2 type [NOT NULL][:=expr2], /*如果一个字段限定NOT NULL,那么它必须拥有一个初始值*/... /*所有没有初始化的字段都会初始为NULLfieldn type [NOT NULL][:=exprn]);4. %ROWTYPE答:返回一个基于数据库定义的类型DECLAREv_StuRec Student%ROWTYPE; /*Student为表的名字*/注:与3中定一个record相比,一步就完成,而3中定义分二步:a. 所有的成员变量都要申明; b. 实例化变量;5. TABLE类型答:TYPE tabletype IS TABLE OF type INDEX BY BINARY_INTEGER;例:DECLARETYPE t_StuTable IS TABLE OF Student%ROWTYPE INDEX BY BINARY_INTERGER;v_Student t_StuTable;BEGINSELECT * INTO v_Student(100) FROM Student WHERE id = 1001;END;注:1) 行的数目的限制由BINARY_INTEGER的范围决定;6. 变量的作用域和可见性答:1) 执行块里可以嵌入执行块;2) 里层执行块的变量对外层不可见;3) 里层执行块对外层执行块变量的修改会影响外层块变量的值;第四章1. 条件语句答:IF boolean_expression1 THEN...ELSIF boolean_expression2 THEN /*注意是ELSIF,而不是ELSEIF*/... /*ELSE语句不是必须的,但END IF;是必须的*/ELSE...END IF;2. 循环语句答:1) Loop...IF boolean_expr THEN /* */EXIT; /* EXIT WHEN boolean_expr */END IF; /* */END LOOP;2) WHILE boolean_expr LOOP...END LOOP;3) FOR loop_counter IN [REVERSE] low_blound..high_bound LOOP...END LOOP;注:a. 加上REVERSE 表示递减,从结束边界到起始边界,递减步长为一;b. low_blound 起始边界; high_bound 结束边界;3. GOTO语句答:GOTO label_name;1) 只能由内部块跳往外部块;2) 设置标签:<<label_name>>3) 示例:LOOP...IF D%ROWCOUNT = 50 THENGOTO l_close;END IF;...END LOOP;<<l_close>>;...4. NULL语句答:在语句块中加空语句,用于补充语句的完整性。
(转)oracle存储过程带游标作为OUT参数输出
(转)oracle存储过程带游标作为OUT参数输出(转)oracle 存储过程带游标作为OUT参数输出存储过程返回OUT参数的游标例⼦。
包中带过程要⾃⼰定义⼀个type [cur_name] is ref cursor游标,返回的时候就直接 procedure AAA(变量名 out [cur_name])如此申明OUT变量存储过程⽤系统默认的 sys_refcursor 游标类型定义变量就OK了--=====================================================Sql代码:--PL/SQL Code (包中带过程) 过程带游标的OUT参数,返回游标(ref cursor)create or replace package my_pack astype my_ref_cursor is ref cursor;procedure getMyCursor(val out my_ref_cursor);end my_pack;create or replace package body my_pack asprocedure getMyCursor(val out my_ref_cursor)isbeginopen val for select * from student;end;end my_pack;--=====================================================Sql代码:--PL/SQL Code(存储过程) 带游标的OUT参数,返回游标(ref cursor)create or replace procedure retCursor(ret_cursor out sys_refcursor)isret_cursor_value sys_refcursor;beginopen ret_cursor_value for select * from student;ret_cursor:=ret_cursor_value;end retCursor;--=====================================================下⾯是个每个学⽣求平均值的存储过程。
Oracle存储过程及调用
Oracle存储过程及调⽤Oracle存储过程语法Oracle的存储过程语法如下:create procedure 存储过程名称(随便取)is在这⾥可以定义常量、变量、游标、复杂数据类型这⾥可以定义变量、常量begin执⾏部分end;(2)带参数的存储过程语法:create procedure 存储过程名称(随便取) (变量1 数据类型,变量2 数据类型,...,变量n 数据类型)is在这⾥可以定义常量、变量、游标、复杂数据类型这⾥可以定义变量、常量begin执⾏部分end;(3)带输⼊、输出参数的存储过程语法:create procedure 存储过程名称(随便取) (变量1 in(或out) 数据类型,变量2 in(或out) 数据类型,...,变量n in(或out) 数据类型)is在这⾥可以定义常量、变量、游标、复杂数据类型这⾥可以定义变量、常量begin执⾏部分end;注意:⽤上⾯的语法创建存储过程时可能会碰到数据库中已经有了同名的存储过程,这样Oracle就会弹框报错,说名字已被现有对象使⽤。
解决⽅法有两种: ⽅法⼀:换个存储过程名 ⽅法⼆:在最开头的create procedure 之间加上 or replace 关键字,例如:create or replace procedure 存储过程名称。
但是这种⽅法不建议使⽤,因为这种⽅法会把之前同名的存储过程替换为你当前写的这个存储过程案例⼀:没参数的存储过程create replace procedure procedure_1isbegindbms_output.put_line('procedure_1.......');end;存储过程案例⼆:带参数的的存储过程create procedure procedure_2(v_i number,v_j number)isv_m number(5);begindbms_output.put_line('procedure_2.......');v_m := v_i + v_j;dbms_output.put_line(v_i||' + '||v_j||' = '||v_m);end;存储过程案例三:带输⼊、输出参数的存储过程存储过程的参数分为输⼊参数和输出参数,输⼊参数:输⼊参数⼀般会在变量名和数据类型之间加in来表⽰该参数是输⼊参数输出参数:输出参数⼀般会在变量名和数据类型之间加out来表⽰该变量是输出参数不写in和out的话,默认为输⼊参数create procedure procedure_3(v_i in number,v_j in number ,v_m out number)isbegindbms_output.put_line('procedure_3.......');v_m:=v_i - v_j;dbms_output.put_line(v_i||' - '||v_j||' = '||v_m);end;PL/SQL块中调⽤存储过程下⾯以调⽤上⾯三个存储过程为例declarev_param1 number(5):=2;v_param2 number(5):=8;v_result number(5);begin--调⽤上⾯案例⼀的存储过程procedure_1();--调⽤上⾯案例⼆的存储过程procedure_2(v_param1,v_param2);--调⽤上⾯案例三的存储过程procedure_3(v_param1,v_param2,v_result);dbms_output.put_line(v_result);end;/*执⾏结果:*/procedure_1.......procedure_2.......2 + 8 = 10procedure_3.......2 - 8 = -610java调⽤存储过程案例⼀:java调⽤没有返回值的存储过程要求:编写⼀个像数据库emp表插⼊⼀条编号为6666,姓名为张三,职位为MANAGER的记录/*存储过程*/create procedure procedure_4(v_empno emp.empno%type,v_ename emp.ename%type,v_job emp.job%type )isbegininsert into emp (empno,ename,job) values (v_empno,v_ename,v_job);end;//java调⽤存储过程public static void main(String[] args) {Connection conn=null;CallableStatement cs=null;ResultSet rs=null;//java调⽤存储过程try {Class.forName("oracle.jdbc.OracleDriver");conn=DriverManager.getConnection("jdbc:oracle:thin:@127.0.01:1521:orcl", "scott", "tiger");cs=conn.prepareCall("{call procedure_4(?,?,?)}");//给输⼊参数赋值cs.setInt(1, 6666);cs.setString(2, "张三");cs.setString(3, "MANAGER");cs.execute();//执⾏} catch (Exception e) {e.printStackTrace();}finally{closeResource(conn,cs,rs);//关闭资源}}//执⾏后就会向数据库的emp表中插⼊⼀条编号为6666,姓名为张三,职位为MANAGER的记录案例⼆:java调⽤返回单列单⾏的存储过程要求:编写⼀个根据员⼯编号查找员⼯姓名的存储过程,并⽤java调⽤该存储过程/*存储过程*/create procedure procedure_5(v_empno in emp.empno%type,v_ename out emp.ename%type)isbeginselect ename into v_ename from emp where empno=v_empno;end;//java调⽤存储过程public static void main(String[] args) {Connection conn=null;CallableStatement cs=null;ResultSet rs=null;try {Class.forName("oracle.jdbc.OracleDriver");conn=DriverManager.getConnection("jdbc:oracle:thin:@127.0.01:1521:orcl", "scott","tiger");cs=conn.prepareCall("{call procedure_5(?,?)}");cs.setInt(1, 6666);//给输⼊参数赋值/*指定输出参数的数据类型语法:oracle.jdbc.OracleTypes.输出参数的数据类型此例输出参数的数据类型是varchar,所以是oracle.jdbc.OracleTypes.VARCHAR*/cs.registerOutParameter(2, oracle.jdbc.OracleTypes.VARCHAR);cs.execute();//执⾏//获取输出参数的值,位置要和输出参数对应?的位置对应起来,该例输出参数对应第2个问号,⽽且输出参数的数据类型为字符型,所以是cs.getString(2) String a=cs.getString(2);System.out.println("员⼯姓名:"+a);} catch (Exception e) {e.printStackTrace();}finally{closeResource(conn,cs,rs);//关闭资源}}/*执⾏结果,控制台打印:*/结果:员⼯姓名:张三案例三:java调⽤返回单⾏多列的存储过程要求:编写⼀个根据员⼯编号查找员⼯姓名、职位和⼯资的存储过程,并⽤java调⽤该存储过程/*存储过程*/create procedure procedure_6(v_empno in emp.empno%type,v_ename out emp.ename%type,v_job out emp.job%type,v_sal out emp.sal%type)isbeginselect ename,job,sal into v_ename,v_job,v_sal from emp where empno=v_empno;end;//java调⽤存储过程public static void main(String[] args) {Connection conn=null;CallableStatement cs=null;ResultSet rs=null;try {Class.forName("oracle.jdbc.OracleDriver");conn=DriverManager.getConnection("jdbc:oracle:thin:@127.0.01:1521:orcl", "scott","tiger");cs=conn.prepareCall("{call procedure_6(?,?,?,?)}");cs.setInt(1, 7788);//指定输出参数的数据类型,注意:顺序要对应起来cs.registerOutParameter(2, oracle.jdbc.OracleTypes.VARCHAR);cs.registerOutParameter(3, oracle.jdbc.OracleTypes.VARCHAR);cs.registerOutParameter(4, oracle.jdbc.OracleTypes.DOUBLE);cs.execute();//执⾏//获取返回值String ename=cs.getString(2);//获取姓名String job=cs.getString(3);//获取职位double sal=cs.getDouble(4);//获取薪⽔System.out.println("员⼯编号为7788的姓名为:"+ename+" 职位是:"+job+" 薪⽔是:"+sal);} catch (Exception e) {e.printStackTrace();}finally{closeResource(conn,cs,rs);//关闭资源}}/*执⾏结果,控制台打印:*/员⼯编号为7788的姓名为:SCOTT 职位是:ANALYST 薪⽔是:3000.0案例四:java调⽤返回多⾏多列(返回列表)的存储过程要求:编写⼀个根据部门编号查找部门所有员⼯信息的存储过程,并⽤java调⽤该存储过程/*定义游标*/create package my_package astype emp_cursor is ref cursor;end my_package;/*存储过程*/create procedure procedure_7(v_deptno in emp.deptno%type,emp_cursor out my_package.emp_cursor)isbeginopen emp_cursor for select * from emp where deptno=v_deptno;end;//java调⽤存储过程public static void main(String[] args) {Connection conn=null;CallableStatement cs=null;ResultSet rs=null;try {Class.forName("oracle.jdbc.OracleDriver");conn=DriverManager.getConnection("jdbc:oracle:thin:@127.0.01:1521:orcl", "scott","tiger");cs=conn.prepareCall("{call procedure_7(?,?)}");cs.setInt(1, 20);//给输⼊参数赋值cs.registerOutParameter(2, oracle.jdbc.OracleTypes.CURSOR );//指定输出参数的数据类型cs.execute();rs=(ResultSet) cs.getObject(2);//获取输出参数的值while(rs.next()){//顺序为数据库中字段前后顺序,例如数据库emp表中第5列为hiredate,数据类型为Date,所以获取第5列值时就应该⽤rs.getDate(5) System.out.println(rs.getInt(1)+" "+rs.getString(2)+" "+rs.getDate(5));}} catch (Exception e) {e.printStackTrace();}finally{closeResource(conn,cs,rs);//关闭资源}}/*以下就是20号部门所有员⼯的信息,这⾥为⽅便我们只打印了编号、姓名和⼊职时间运⾏结果,控制台打印:*/7369 SMITH 1980-12-177566 JONES 1981-04-027788 SCOTT 1987-04-197876 ADAMS 1987-05-237902 FORD 1981-12-03这是上⾯java调⽤存储过程代码中关闭资源⽅法的代码public static void closeResource(Connection conn,CallableStatement cs,ResultSet rs){if(rs!=null){try {rs.close();} catch (SQLException e) {e.printStackTrace();}}if(cs!=null){try {cs.close();} catch (SQLException e) {e.printStackTrace();}}if(conn!=null){try {conn.close();} catch (SQLException e) {e.printStackTrace();}}}最后给个应⽤,分页的存储过程分页存储过程:/*定义游标*/create package page_package astype page_cursor is ref cursor;end page_package;/*存储过程*/create procedure pro_paging (v_page_size in number,--每页显⽰多少条v_page_count out number,--总页数v_current_page in number,--当前页v_total_count out number,--记录总条数emp_cursor out page_package.page_cursor--返回查询结果集的游标)isv_begin number(5):=v_page_size*(v_current_page-1)+1;--查询起始位置v_end number(5):=v_page_size*v_current_page;--查询结束位置v_sql varchar2(1000):='select empno,ename from(select a.empno,a.ename,rownum rn from(select empno,ename from emp) awhere rownum<='|| v_end ||') bwhere b.rn>='||v_begin;/*不能像下⾯这么写,不然调⽤该存储过程时会报类型不⼀致的错,因为最⾥⾯查的只有empno,ename,因此外⾯也要和⾥⾯保持⼀致 v_sql varchar2(1000):=\'select * from(select a.*,rownum rn from(select empno,ename from emp) awhere rownum<=\'|| v_end ||\') bwhere b.rn>='||v_begin;*/v_ename varchar2(10);v_empno number(4);beginopen emp_cursor for v_sql;loopfetch emp_cursor into v_empno,v_ename;exit when emp_cursor%notfound;dbms_output.put_line(v_empno||' '||v_ename);end loop;v_sql:='select count(empno) from emp';execute immediate v_sql into v_total_count;if(mod(v_total_count,v_page_size)=0) thenv_page_count:=v_total_count/v_page_size;elsev_page_count:=trunc(v_total_count/v_page_size)+1;end if;dbms_output.put_line('共 '||v_total_count||' 条记录');dbms_output.put_line('共 '||v_page_count||' 页');dbms_output.put_line('当前页: '||v_current_page);dbms_output.put_line('每页显⽰ '||v_page_size||' 条');end;Java调⽤的话和上⾯java调⽤存储过程的例⼦⼀样。
PLSQL基本操作手册
PL/SQL基本操作手册PL/SQL(Procedural Language/Structured Query Language)是一种基于SQL 语言的过程编程语言,它在Oracle数据库中非常常见。
本文将介绍PL/SQL的基本操作,如变量、控制语句、游标等。
变量和常量变量可以使用DECLARE语句声明。
在代码中,变量必须指定它们的类型,例如NUMBER、VARCHAR2或BOOLEAN。
DECLAREv_employee_id NUMBER:=100;v_employee_name VARCHAR2(50) :='John Doe';v_is_hired BOOLEAN:=TRUE;BEGIN-- code goes hereEND;常量是一个不可变的参数,可以使用CONSTANT关键字定义。
常量的值不会在程序中更改。
DECLAREc_tax_rate CONSTANT NUMBER(4, 2) :=0.08;BEGIN-- code goes hereEND;控制语句控制语句提供了决策和循环结构。
IF语句IF语句用于对一个表达式进行测试,以确定哪个分支应该执行。
IF expression THEN-- code goes hereELSIF expression THEN-- code goes hereELSE-- code goes hereEND IF;CASE语句CASE语句用于检查多个可能的条件。
CASE expressionWHEN value1 THEN-- code goes hereWHEN value2 THEN-- code goes hereELSE-- code goes hereEND CASE;LOOP语句LOOP语句用于无限的循环,可以通过某些条件来终止循环。
LOOP-- code goes hereEXIT WHEN expression;END LOOP;WHILE语句WHILE语句用于执行一系列语句,只要指定条件为TRUE。
oracle存储过程declare的写法
oracle存储过程declare的写法Oracle存储过程是一种预编译的程序,它可以在数据库中存储并重复使用。
在Oracle中,存储过程可以使用DECLARE语句来定义变量和游标,以及执行其他必要的操作。
下面是Oracle存储过程DECLARE 语句的写法。
1. 定义变量在Oracle存储过程中,可以使用DECLARE语句来定义变量。
变量可以是任何数据类型,如整数、字符、日期等。
以下是定义整数变量的示例:DECLAREnum INTEGER;可以使用多个DECLARE语句来定义多个变量。
例如:DECLAREnum1 INTEGER;num2 INTEGER;2. 定义游标游标是一种用于遍历查询结果集的机制。
在Oracle存储过程中,可以使用DECLARE语句来定义游标。
以下是定义游标的示例:DECLARECURSOR cur_emp ISSELECT * FROM employees;可以使用多个DECLARE语句来定义多个游标。
例如:DECLARECURSOR cur_dept ISSELECT * FROM departments;CURSOR cur_job ISSELECT * FROM jobs;3. 执行其他操作除了定义变量和游标之外,还可以使用DECLARE语句来执行其他必要的操作。
例如,可以使用DECLARE语句来定义异常处理程序。
以下是定义异常处理程序的示例:DECLAREex_no_data_found EXCEPTION;PRAGMA EXCEPTION_INIT(ex_no_data_found, -1403);在上面的示例中,定义了一个名为ex_no_data_found的异常处理程序,并使用PRAGMA EXCEPTION_INIT语句将其初始化为ORA-01403异常。
总结在Oracle存储过程中,DECLARE语句是定义变量、游标和异常处理程序等必要元素的关键。
oracle存储过程详细介绍(创建,删除存储过程,参数传递等)
oracle存储过程详细介绍(创建,删除存储过程,参数传递等)oracle 创建,删除存储过程,参数传递,创建,删除存储函数,存储过程和函数的查看,包,系统包存储过程和函数也是⼀种PL/SQL块,是存⼊数据库的PL/SQL块。
但存储过程和函数不同于已经介绍过的PL/SQL程序,我们通常把PL/SQL程序称为⽆名块,⽽存储过程和函数是以命名的⽅式存储于数据库中的。
和PL/SQL程序相⽐,存储过程有很多优点,具体归纳如下:* 存储过程和函数以命名的数据库对象形式存储于数据库当中。
存储在数据库中的优点是很明显的,因为代码不保存在本地,⽤户可以在任何客户机上登录到数据库,并调⽤或修改代码。
* 存储过程和函数可由数据库提供安全保证,要想使⽤存储过程和函数,需要有存储过程和函数的所有者的授权,只有被授权的⽤户或创建者本⾝才能执⾏存储过程或调⽤函数。
* 存储过程和函数的信息是写⼊数据字典的,所以存储过程可以看作是⼀个公⽤模块,⽤户编写的PL/SQL程序或其他存储过程都可以调⽤它(但存储过程和函数不能调⽤PL/SQL程序)。
⼀个重复使⽤的功能,可以设计成为存储过程,⽐如:显⽰⼀张⼯资统计表,可以设计成为存储过程;⼀个经常调⽤的计算,可以设计成为存储函数;根据雇员编号返回雇员的姓名,可以设计成存储函数。
* 像其他⾼级语⾔的过程和函数⼀样,可以传递参数给存储过程或函数,参数的传递也有多种⽅式。
存储过程可以有返回值,也可以没有返回值,存储过程的返回值必须通过参数带回;函数有⼀定的数据类型,像其他的标准函数⼀样,我们可以通过对函数名的调⽤返回函数值。
存储过程和函数需要进⾏编译,以排除语法错误,只有编译通过才能调⽤。
创建和删除存储过程创建存储过程,需要有CREATE PROCEDURE或CREATE ANY PROCEDURE的系统权限。
该权限可由系统管理员授予。
创建⼀个存储过程的基本语句如下:CREATE [OR REPLACE] PROCEDURE 存储过程名[(参数[IN|OUT|IN OUT] 数据类型...)]{AS|IS}[说明部分]BEGIN可执⾏部分[EXCEPTION错误处理部分]END [过程名];其中:可选关键字OR REPLACE 表⽰如果存储过程已经存在,则⽤新的存储过程覆盖,通常⽤于存储过程的重建。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
end mypackage;
使用:
DECLARE
v_my_rec mypackage.recordtype;
BEGIN
mypackage.tempprocedure2(10,v_my_rec);
DBMS_OUTPUT.PUT_LINE(v_my_rec.v_dname||' '||v_my_rec.v_loc);
一、游标变量
例:使用游标变量取出部门表的所有相关数据。
法I:
DECLARE
TYPE cursortype IS REF CURSOR;
v_cs cursortype;--区别于法II
v_dept_info dept%ROWTYPE;
TYPE type_emp_info IS RECORD (
END LOOP;
CLOSE v_cs;
END;
过程的使用:
法I:
begin
myfirstpro;
end;
法II:
exec myfirstpro;
例:写一个过程,向dept表插入数据.
CREATE OR REPLACE PROCEDURE insert_dept_pro(t_deptno IN NUMBER,t_dname IN VARCHAR2,t_loc IN VARCHAR2)
v_sal emp.sal%TYPE
);
v_emp_info type_emp_info;
BEGIN
OPEN v_cs FOR SELECT * FROM dept;
LOOP
FETCH v_cs INTO v_dept_info;
EXIT WHEN v_cs%NOTFOUND;
DBMS_OUTPUT.PUT_LINE('第'||v_cs%ROWCOUNT||'行:'||v_dept_info.deptno||' '||v_dept_info.dname||' '||v_dept_info.loc);
EXIT WHEN v_cs%NOTFOUND;
DBMS_OUTPUT.PUT_LINE('第'||v_cs%ROWCOUNT||'行:'||v_dept_info.deptno||' '||v_dept_info.dname||' '||v_dept_info.loc);
END LOOP;
CLOSE v_cs;
END;
例:给定一个员工编号,通过过程得到该员工的上司编号.
CREATE OR REPLACE PROCEDURE get_mgr_by_empno(t_num IN OUT NUMBER)
IS
BEGIN
SELECT mgr INTO t_num FROM emp WHERE empno=t_num;
end;
例:给过程一个员工编号,返回员工的姓名;
CREATE OR REPLACE FUNCTION get_ename_by_no(t_empno IN NUMBER)
RETURN VARCHAR2
IS
t_ename emp.ename%TYPE;
BEGIN
SELECT ename INTO t_ename FROM emp WHERE empno=t_empno;
v_empno emp.empno%TYPE,
v_ename emp.ename%TYPE,
v_sal emp.sal%TYPE
);
v_emp_info type_emp_info;
BEGIN
OPEN v_cs FOR SELECT * FROM dept;
LOOP
FETCH v_cs INTO v_dept_info;
END;
使用:
DECLARE Байду номын сангаас
v_num emp.empno%TYPE:=&no;
BEGIN
get_mgr_by_empno(v_num);
DBMS_OUTPUT.PUT_LINE('取出的员工上司编号为'||v_num);
END;
三、包:包含两部分内容包规范和包体
定义包规范:
CREATE OR REPLACE PACKAGE "SCOTT"."MYPACKAGE" as
v_ename emp.ename%TYPE,
v_sal emp.sal%TYPE
);
v_emp_info type_emp_info;
BEGIN
OPEN v_cs FOR SELECT * FROM dept;
LOOP
FETCH v_cs INTO v_dept_info;
EXIT WHEN v_cs%NOTFOUND;
DBMS_OUTPUT.PUT_LINE('第'||v_cs%ROWCOUNT||'行:'||v_dept_info.deptno||' '||v_dept_info.dname||' '||v_dept_info.loc);
END LOOP;
CLOSE v_cs;
OPEN v_cs FOR SELECT empno,ename,sal FROM emp;
LOOP
FETCH v_cs INTO v_emp_info;
EXIT WHEN v_cs%NOTFOUND;
DBMS_OUTPUT.PUT_LINE('第'||v_cs%ROWCOUNT||'行:'||v_emp_info.v_empno||' '||v_emp_info.v_ename||' '||v_emp_info.v_sal);
BEGIN
OPEN v_vc FOR SELECT * FROM dept;
RETURN v_vc;
END;
使用:
DECLARE
v_test_rc SYS_REFCURSOR;
v_dept_info dept%ROWTYPE;
BEGIN
v_test_rc:=test_cur;
LOOP
END LOOP;
CLOSE v_cs;
OPEN v_cs FOR SELECT empno,ename,sal FROM emp;
LOOP
FETCH v_cs INTO v_emp_info;
EXIT WHEN v_cs%NOTFOUND;
DBMS_OUTPUT.PUT_LINE('第'||v_cs%ROWCOUNT||'行:'||v_emp_info.v_empno||' '||v_emp_info.v_ename||' '||v_emp_info.v_sal);
异常处理语句段;
end;
例:
CREATE OR REPLACE PROCEDURE myfirstpro
AS
v_cs SYS_REFCURSOR;--区别于法I
v_dept_info dept%ROWTYPE;
TYPE type_emp_info IS RECORD (
v_empno emp.empno%TYPE,
print v_name;
函数和过程的区别:函数偏向于执行的结果;而过程偏向功能的实现。
返回游标:
例:返回dept标的游标,对表数据进行显示。
CREATE OR REPLACE FUNCTION test_cur
RETURN SYS_REFCURSOR
AS
v_vc SYS_REFCURSOR;
OPEN v_cs FOR SELECT empno,ename,sal FROM emp;
LOOP
FETCH v_cs INTO v_emp_info;
EXIT WHEN v_cs%NOTFOUND;
DBMS_OUTPUT.PUT_LINE('第'||v_cs%ROWCOUNT||'行:'||v_emp_info.v_empno||' '||v_emp_info.v_ename||' '||v_emp_info.v_sal);
FETCH v_test_rc INTO v_dept_info;
EXIT WHEN v_test_rc%NOTFOUND;
DBMS_OUTPUT.PUT_LINE('第'||v_test_rc%ROWCOUNT||
'行:'||v_dept_info.deptno||'--'||v_dept_info.dname||'--'||v_dept_info.loc);
IS
BEGIN
INSERT INTO dept VALUES(t_deptno,t_dname,t_loc);
COMMIT;
END;
使用:
exec insert_dept_pro(70,'AAA','BBB');
例:给过程一个员工编号,通过输出参数得到员工的姓名;
CREATE OR REPLACE PROCEDURE sel_ename_by_no(t_empno IN NUMBER,t_dname OUT VARCHAR2)