Oracle12C--子程序(三十九)

本文介绍Oracle数据库中子程序的概念与应用,包括过程与函数的区别、创建方法及权限说明,并通过实例演示如何定义与调用过程和函数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

知识点的梳理:

  • 子程序分为:"过程"和"函数"两类,虽然统称子程序,但实际上两者有很大不同;
    • "过程"也可以被称为"存储过程",其与PL/SQL的关系:过程(存储过程)=过程的声明 + PL/SQL
    • 两者区别:
      • 函数可以有返回值;
      • 过程只能依靠OUTIN OUT返回数据
  • 调用过程的语法为:exec 过程名称
  • 子程序就是将定义的PL/SQL程序块在过程或函数中进行统一的管理;
  • 查询子程序的详细定义,可以使用user_source数据字典;
  • 子程序有3中参数模式:IN(默认),IN OUT,OUT;
  • 使用"PRAGMA AUTONOMOUS_TRANSACTION;"可以启动一个子事务,子事务的操作与主事务无关;

      

  • 子程序定义
    • Oracle中,将重复代码块封装到一个结构体中,该结构体被称为子程序;
      • 子程序中的代码块为Oracle对象,其对象信息保存在对应的数据字典中;
    • 创建子程序所需的权限,下表不包含触发器权限:

create any procedur

为任意用户创建存储过程的权限

create procedure

为用户创建存储过程的权限

alter procedure

修改拥有的存储过程权限

execute any procedure

执行任意存储过程的权限

execute function

执行存储函数的权限

execute procedure

执行用户存储过程的权限

drop any procedure

删除任意存储过程的权限

  • 定义过程
    • 定义:"过程"是指大型数据库中专门定义的一组SQL语句集,它可以定义用户操作参数,且存在于数据库中,使用时直接调用即可。
    • 语法:定义过程

CREATE [OR REPLACE] PROCEDURE 过程名称([参数名称 [参数模式] NOCOPY 数据类型 [,参数名称 [参数模式] NOCOPY 数据类型 ,....]])

[AUTHID [DEFINER | CURRENT_USER]]

AS | IS

[PRAGMA AUTONOMOUS_TRANSACTION;]

声明部分;

BEGIN

程序部门;

EXCEPTION

异常处理;

END;

/

本语法中的部分解释如下:
1.参数中定义的参数模式表示过程的数据接收操作,一般分为IN,OUT,IN OUT 3 类;
2.CREATE [OR REPLACE]:表示创建或替换过程,如果此过程存在则替换,如果不存在则创建一个新的;
3.AUTHID子句:定义了一个过程的所有者权限,DEFINER(默认)表示定义者权限执行,或者使用CURRENT_USER覆盖程序的默认行为,变为使用者权限执行;
4.PRAGMA AUTONOMOUS_TRANSACTION:表示由过程启动一个自治事务,自治事务可以让主事务挂起,在过程中执行完SQL后,由用户处理提交或回滚自治事务,然后再恢复主事务;

  • 示例1:定义一个简单的过程

CREATE OR REPLACE PROCEDURE mldn_proc

AS

BEGIN

DBMS_OUTPUT.put_line('www.java.cn') ;

END;

/

调用过程:EXEC mldn_proc
执行结果:
www.
java.cn

方式2:将"AS"替换为"IS"

CREATE OR REPLACE PROCEDURE mldn_proc

IS

BEGIN

DBMS_OUTPUT.put_line('www.java.cn') ;

END;

/

执行结果相同

  • 示例2:定义一个带参数的过程,根据雇员编号(参数)找到雇员姓名及工资

CREATE OR REPLACE PROCEDURE get_emp_info_proc(p_eno emp.empno%TYPE)

AS

v_ename emp.ename%TYPE ;

v_sal emp.sal%TYPE ;

v_count NUMBER ;

BEGIN

SELECT COUNT(empno) INTO v_count FROM emp WHERE empno=p_eno ;

IF v_count = 0 THEN -- 没有发现数据

RETURN ; -- 结束过程调用

END IF ;

SELECT ename,sal INTO v_ename,v_sal FROM emp WHERE empno=p_eno ;

DBMS_OUTPUT.put_line('编号为' || p_eno || '的雇员姓名:' || v_ename || ',工资:' || v_sal) ;

END;

/

调用过程:exec get_emp_info_proc(7369)
执行结果:
编号为7369的雇员姓名:SMITH,工资:10800
分析:
建立过程时定义了一个接收参数(
p_eno),则用户在调用此过程时就需要传入一个与之类型相符的数值。在过程之中,会首先使用COUNT()函数来判断是否存在指定的雇员信息,如果不存在则统计结果为0,可直接使用RETuRN结束方法的调用

  • 示例3:将增加数据的操作定义为过程

CREATE OR REPLACE PROCEDURE dept_insert_proc(

p_dno dept.deptno%TYPE,

p_dna dept.dname%TYPE,

p_dlo dept.loc%TYPE)

AS

v_deptCount NUMBER ; -- 保存COUNT()函数结果

BEGIN

SELECT COUNT(deptno) INTO v_deptCount FROM dept WHERE deptno=p_dno ; -- 统计

IF v_deptCount > 0 THEN -- 有此编号的部门

RAISE_APPLICATION_ERROR(-20789,'增加失败:该部门已存在!') ;

ELSE

INSERT INTO dept(deptno,dname,loc) VALUES (p_dno,p_dna,p_dlo) ;

DBMS_OUTPUT.put_line('新部门增加成功!') ;

COMMIT ;

END IF ;

EXCEPTION

WHEN others THEN

DBMS_OUTPUT.put_line('SQLERRM = ' || SQLERRM) ;

ROLLBACK ; -- 事务回滚

END ;

/

调用过程:
部门编号重复:exec dept_insert_proc(10,'MLDN','北京')
运行结果:SQLERRM = ORA-20789: 增加失败:该部门已存在!
 

部门编号不重复:exec dept_insert_proc(15,'微软','北京')
运行结果:新部门增加成功!
 

  • 定义函数
    • 用户定义的函数,被SQL语句或PL/SQL直接调用;
    • 语法:定义函数

CREATE [OR REPLACE] FUNCTION 函数名([参数 ,[参数,.....]])

RETURN 返回值类型

[AUTHID {DEFINER | CURRENT_USER}]

AS | IS

[PRAGMA AUTONOMOUS_TRANSACTION;]

声明部分;

BEGIN

程序部门;

[RETURN 返回值;]

[EXCEPTION

异常处理]

END [函数名];

/

  • 示例1定义函数,通过雇员编号查找此雇员的月薪

CREATE OR REPLACE FUNCTION get_salary_fun(p_eno emp.empno%TYPE)

RETURN NUMBER

AS

v_salary emp.sal%TYPE ;

BEGIN

SELECT sal + nvl(comm,0) INTO v_salary FROM emp WHERE empno=p_eno ;

RETURN v_salary ;

END;

/

分析:
该函数会根据雇员的编号查询出每位雇员的月薪,

同时将查询出来的月薪通过RETURN返回给调用处

  • 示例2:通过PL/SQL块验证函数

 

DECLARE

v_salary NUMBER ;

BEGIN

v_salary := get_salary_fun(7369) ;

DBMS_OUTPUT.put_line('雇员7369的工资为:' || v_salary) ;

END ;

/

运行结果:
雇员7369的工资为:800

此示例使用了PL/SQL进行函数调用,用户也可以定义一个过程,通过过程来调用函数,示例代码:

扩展示例:定义过程调用函数

CREATE OR REPLACE PROCEDURE invoke_proc

AS

v_salary NUMBER ;

BEGIN

v_salary := get_salary_fun(7369) ;

DBMS_OUTPUT.put_line('雇员7369的工资为:' || v_salary) ;

END ;

/

执行过程:exec invoke_proc;
运行结果与上例相同

  • 示例3:除了PL/SQL调用外,还可以像单行函数一样,直接利用SQL调用

SELECT get_salary_fun(7369) FROM dual ;

  • 示例4:可以使用CALL,将函数的返回值设置给变量

VAR v_salary NUMBER ;

CALL get_salary_fun(7369) INTO : v_salary ;

PRINT v_salary ;

运行结果:800

  • 如何选择过程与函数?
    • 根据实际需求,从两个方式区分它们:
      • 过程处理返回值时不如函数方便,过程只能依靠OUTIN OUT参数模式传回数据;
      • 编程语句,例如java,调用过程要比函数更加实用;
<think>好的,我现在要解决用户提到的Oracle 12c安装时出现的INS-30131错误。首先,我需要了解这个错误的具体原因。根据用户提供的引用内容,这个错误通常与临时文件夹的权限或共享设置有关,尤其是在Windows 7系统上安装时。 首先,查看引用中的信息,比如引用[3]和[5]都提到无法访问临时位置的问题,可能涉及C盘的共享权限。用户需要确保C盘是共享的,并且安装程序有足够的权限访问临时目录。此外,引用[4]提到可以通过命令行参数忽略某些检查,比如系统版本检查,这可能也是一个解决办法。 接下来,我需要整理出具体的解决步骤。首先,检查C盘的共享设置,确保共享已启用。然后,设置临时文件夹的权限,允许Everyone或特定用户组有完全控制权。如果这些步骤无效,可能需要使用命令行参数来绕过系统检查,或者关闭用户账户控制(UAC)以减少权限问题。 另外,用户可能遇到的是Windows 7与Oracle 12c的兼容性问题,但根据引用[4]中的方法,可以通过添加参数来忽略系统版本检查。同时,确保安装程序以管理员身份运行,避免权限不足的问题。 需要注意的是,用户可能已经尝试过部分步骤但未完全解决,所以需要一步步确认每个环节是否正确配置。例如,共享C盘的具体步骤是否正确,权限设置是否应用到了所有子文件夹,以及命令行参数的使用是否正确。 最后,如果所有步骤都正确执行但问题依旧,可能需要进一步检查系统日志或Oracle的安装日志,以获取更详细的错误信息。不过根据提供的引用内容,上述步骤应该能够解决大多数情况下的INS-30131错误。</think>### Oracle 12c安装INS-30131错误解决方案 #### 1. 开启C盘共享权限 **步骤:** 1. 右键点击C盘 → 选择 **共享** → **高级共享** 2. 勾选 **共享此文件夹** → 点击 **权限** → 添加 **Everyone** 用户组 → 授予 **完全控制** 权限[^5] 3. 重启计算机使配置生效 #### 2. 设置临时文件夹权限 **路径:** `C:\Windows\Temp` 或 `%TEMP%` **操作:** - 右键文件夹 → **属性** → **安全** → 编辑权限 - 添加 **Everyone** 或当前用户 → 勾选 **完全控制** - 勾选 **替换子容器和对象的所有者** → 应用[^3] #### 3. 关闭用户账户控制(UAC) **步骤:** 1. 打开控制面板 → **用户账户** → **更改用户账户控制设置** 2. 将滑块调至 **从不通知** → 确认 3. 重启系统后重试安装 #### 4. 使用命令行参数绕过系统检查 **命令:** ```bash setup.exe -ignorePrereq -J"-Doracle.install.db.validate.supportedOSCheck=false" ``` 此命令会跳过Oracle对操作系统的兼容性验证[^4]。 #### 5. 检查磁盘映射与管理员权限 - 确保安装文件路径不包含中文或特殊字符 - 右键点击安装程序 → **以管理员身份运行** - 若为虚拟机,检查磁盘映射是否正常[^2] #### 6. 验证服务依赖项 **操作:** - 按下 `Win+R` → 输入 `services.msc` - 确保 **Server** 和 **Workstation** 服务已启动且设置为自动 --- ### 故障排除补充 - **日志分析:** 检查 `installActions.log`(位于安装日志目录)获取具体错误代码 - **系统兼容性:** Oracle 12c官方支持Windows Server系统,Windows 7需通过参数绕过检查[^1] ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值