Oracle存储过程详解(引用)+补充
一、过程 (存储过程) 过程是一个能执行某个特定操作的子程序。使用CREATE OR REPLACE创建或者替换保存在数据库中的一个子程序。 示例1: 声明存储过程,该过程返回dept表行数 DECLARE PROCEDURE getDeptCount AS deptCount INT;BEGIN SELECT COUNT(*) INTO d
一、过程 (存储过程)
过程是一个能执行某个特定操作的子程序。使用CREATE OR REPLACE创建或者替换保存在数据库中的一个子程序。
示例1:声明存储过程,该过程返回dept表行数<span>DECLARE</span> PROCEDURE getDeptCount <span>AS</span> deptCount INT; BEGIN <span>SELECT</span> COUNT(*) INTO deptCount FROM DEPT; DBMS_OUTPUT.PUT_LINE(<span>'DEPT表的共有记录数:'||deptCount);</span> <span>END</span> getDeptCount; BEGIN getDeptCount[()]; <span>END</span>;로그인 후 복사
注意:此存储过程getDeptCount只在块运行时有效。
示例2:创建不带参数的存储过程,该过程返回dept表行数CREATE <span>OR</span> REPLACE PROCEDURE getDeptCount <span>AS</span> | <span>IS</span> deptCount int; BEGIN <span>SELECT</span> COUNT(*) INTO deptCount FROM dept; DBMS_OUTPUT.PUT_LINE(<span>'dept表共有'||deptCount||'行记录');</span> <span>END</span> [getDeptCount];로그인 후 복사
当我们创建的存储过程没有参数时,在存储过程名字后面不能有括号。在AS或者IS后至BEGIN之前是声明部分,存储过程中的声明不使用DECLARE关键字。同匿名PL/SQL块一样,EXCEPTION和声明部分都是可选的。
当我们创建的过程带有错误时,我们可以通过SELECT * FROM USER_ERRORS查看,或者使用SHOW ERRORS [ PROCEDURE Proc_Name]查看。
使用以下代码可以执行存储过程:BEGIN getDeptCount; <span>END</span>; 以上存储过程还可以通过以下代码来简化调用: EXEC getDeptCount[;] <span>CALL</span> getDeptCount();로그인 후 복사
注意:
- 并不是所有的存储过程都可以用这种方式来调用
- 定义无参存储过程时,存储过程名后不能加()
- 在块中或是通过EXEC调用存储过程时可以省略()
- 通过CALL调用无参存储过程必须加上()
示例3:创建带有输入参数的存储过程,该过程通过员工编号打印工资额
CREATE <span>OR</span> REPLACE PROCEDURE getSalaryByEmpNo(eNo NUMBER) --参数的数据类型不能指定长度 <span>AS</span> salary emp.sal%TYPE; BEGIN <span>SELECT</span> SAL INTO salary FROM EMP WHERE EMPNO=eNo; DBMS_OUTPUT.PUT_LINE(eNo||<span>'号员工的工资为'||salary);</span> EXCEPTION <span>WHEN</span> NO_DATA_FOUND <span>THEN</span> DBMS_OUTPUT.PUT_LINE(<span>'没有找到该编号的员工');</span> <span>END</span>;로그인 후 복사
当定义的存储过程含有参数时,参数的数据类型不能指定长度。参数还有输入和输出之分,本例中没有指定,默认情况为输入参数,也可显示的指定某个参数是输入参数,如(eNo IN NUMBER)。同示例1不同,该例中加入了异常处理。同示例1类似可以使用下面的两种方式调用存储过程:
BEGIN
getSalaryByEmpNo(7788);
END;
或者
EXEC getSalaryByEmpNo(7788); 或者
CALL getSalaryByEmpNo(7788);
但是如果传给一个存储过程的参数是变量时,必须使用BEGIN END块,如下:<span>DECLARE</span> no emp.empNo%TYPE; BEGIN no:=7788; getSalaryByEmpNo(no); <span>END</span>;로그인 후 복사
如果某个包中含有常量,也可以通过如下的方式调用:
EXEC getSalaryByEmpNo(ConstantPackage.no);
但这种方式不能再使用CALL调用。
示例4:创建含有输入和输出参数的存储过程,该过程通过员工编号查找工资额,工资额以输出参数返回CREATE <span>OR</span> REPLACE PROCEDURE getSalaryByEmpNo(eNo <span>IN</span> NUMBER,salary OUT NUMBER) <span>AS</span> BEGIN <span>SELECT</span> SAL INTO salary FROM EMP WHERE EMPNO=eNo; EXCEPTION <span>WHEN</span> NO_DATA_FOUND <span>THEN</span> DBMS_OUTPUT.PUT_LINE(<span>'没有找到该编号的员工');</span> <span>END</span>;로그인 후 복사
当过程中含有输出参数时,调用时必须通过BEGIN END块,不能通过EXEC或CALL调用。如:
<span>DECLARE</span> salary NUMBER(7,2); BEGIN getSalaryByEmpNo(7788,salary); DBMS_OUTPUT.PUT_LINE(salary); <span>END</span>;로그인 후 복사
示例5:创建参数类型既是输入参数也是输出参数的过程
CREATE <span>OR</span> REPLACE PROCEDURE getSalaryByEmpNo(noSalary <span>IN</span> OUT NUMBER) <span>AS</span> BEGIN <span>SELECT</span> SAL INTO noSalary FROM EMP WHERE EMPNO=noSalary; EXCEPTION <span>WHEN</span> NO_DATA_FOUND <span>THEN</span> DBMS_OUTPUT.PUT_LINE(<span>'没有找到该编号的员工');</span> <span>END</span>;로그인 후 복사
调用如下:
<span>DECLARE</span> <span>no</span> NUMBER(7,2); <span>BEGIN</span> <span>no</span>:=7788; getSalaryByEmpNo(<span>no</span>); DBMS_OUTPUT.PUT_LINE(<span>no</span>); <span>END</span>;로그인 후 복사
示例6:创建带有默认值的过程
<span>CREATE</span> <span>OR</span> REPLACE <span>PROCEDURE</span> addEmp ( empNo NUMBER, eName VARCHAR2, job VARCHAR2 :=<span>'CLERK'</span>, mgr NUMBER, hiredate <span>DATE</span> <span>DEFAULT</span> SYSDATE, sal NUMBER <span>DEFAULT</span> 1000, comm NUMBER <span>DEFAULT</span> 0, deptNo NUMBER <span>DEFAULT</span> 30 ) <span>AS</span> <span>BEGIN</span> INSERT <span>INTO</span> emp <span>VALUES</span>(empNo,eName,job,mgr,hiredate,sal,comm,deptNo); <span>END</span>;로그인 후 복사
调用如下:
<span>EXEC</span> addEmp(7776,<span>'zhangsan'</span>,<span>'CODER'</span>,7788,<span>'06-1月-2000'</span>,2000,0,10); --没有使用默认值 <span>EXEC</span> addEmp(7777,<span>'lisi'</span>,<span>'CODER'</span>,7788,<span>'06-1月-2000'</span>,2000,<span>NULL</span>,10); --可以使用NULL值 <span>EXEC</span> addEmp(7778,<span>'wangwu'</span>,mgr=>7788); --使用默认值 <span>EXEC</span> addEmp(mgr=>7788,empNo=>7779,eName=><span>'sunliu'</span>); --更改参数顺序로그인 후 복사
示例7:使用NOCOPY编译提示
当参数是大型数据结构时,如集合、记录和对象实例,把它们的内容全部拷贝给形参会降低执行速度,消耗大量内存。为了防止这样的情况发生,我们可以使用 NOCOPY提示来让编译器按引用传递方式给IN OUT模式的参数。<span>DECLARE</span> TYPE DeptList <span>IS</span> <span>TABLE</span> <span>OF</span> VARCHAR2(10); dList DeptList:=DeptList(<span>'CORESUN'</span>,<span>'CORESUN'</span>,<span>'CORESUN'</span>,<span>'CORESUN'</span>); <span>PROCEDURE</span> My_Proc(d <span>IN</span> <span>OUT</span> NOCOPY DeptList) <span>AS</span>...로그인 후 복사
注意:NOCOPY只是一个提示,而不是指令。即使有时候我们使用了NOCOPY,但编译器有可能仍然会进行值拷贝。通常情况下NOCOPY是可以成功的。
二、维护过程
1、删除存储过程
<span>DROP</span> <span>PROCEDURE</span> Proc_Name;로그인 후 복사
2、查看过程状态
<span>SELECT</span> object_name,status <span>FROM</span> USER_OBJECTS <span>WHERE</span> object_type=<span>'PROCEDURE'</span>;로그인 후 복사
3、重新编译过程
<span>ALTER</span> <span>PROCEDURE</span> Proc_Name COMPILE;로그인 후 복사
4、查看过程代码
<span>SELECT</span> * <span>FROM</span> USER_SOURCE <span>WHERE</span> TYPE=<span>'PROCEDURE'</span>;로그인 후 복사
三、参数的理解
-- 输出参数不可以修改解决的方法有两种
--1 把参数改成输入参数
--2 就是参数改成 可输入输出的参数;
调用过程的 三个方式
1 就是使用call
在只用call方式调用函数的时候,必须加要括号,有参数,还要加参数值
这个方式在命令窗口,调用过程,将不会出现输入的数据.
2 就是使用exec 命令,进行命令调用过程, 使用命令,就必须在命令行里面输入
过程名,这个命令窗口中,可加可不加() ,如果有参数的,就一定要加,还有参数值,参数值的类型要与
变量类型相同.
3 在语句块中进行调用过程,这个方式和命令模式类似,他们都是可要可不要(),
-- 在2 和 3 中的 没有括号的情况是,过程没有参数 ,如果有,就必须要有()
输出参数的特点
1 一个过程中,如果有输出参数(OUT 参数),在调用过程的使用,也要传入一个参数, 这个参数可以不用在调用的地方
进行赋值,就直接传入一个声明好的一个变量,用来接受存储过程中的输出参数的值(OUT 参数)
2 输入参数 值不可以改变在过程中,
注意: 在存储过程中,他的参数类型不可以设置它的大小 ;
例如;<span>CREATE</span> <span>OR</span> REPLACE <span>PROCEDURE</span> hello( p_name <span>IN</span> VARCHAR2(12), p_age <span>OUT</span> NUMBER(10,2) ) <span>IS</span> <span>BEGIN</span>로그인 후 복사
如果有输出参数就必须有有一个参数进行接收 ;
<span>CREATE</span> <span>OR</span> REPLACE <span>PROCEDURE</span> hello( p_name <span>IN</span> VARCHAR2, p_age <span>OUT</span> emp.sal%TYPE ) <span>IS</span> <span>BEGIN</span> <span>SELECT</span> emp.sal + 3131 <span>INTO</span> p_age <span>FROM</span> emp <span>WHERE</span> empno = 7788 ; dbms_output.put_line( p_age); <span>END</span> ;로그인 후 복사
--------- 块中调用方法
<span>DECLARE</span> v_nanme varchar2(12); v_age NUMBER (12,2); <span>BEGIN</span> hello (v_nanme,v_age); dbms_output.put_line(v_age); <span>END</span> ;로그인 후 복사
-- 在这个过程中 传入的v_age 就是接受 存储过程输出参数的值 ; 类似于Java的中的返回值
-- 理解 in out 参数
<span>CREATE</span> <span>OR</span> REPLACE <span>PROCEDURE</span> hello1 ( p_name <span>IN</span> <span>OUT</span> emp.ename%TYPE ) <span>IS</span> <span>BEGIN</span> <span>-- SELECT emp.ename INTO p_name FROM emp ;</span> p_name:=<span>'a;sk , '</span> || p_name ; <span>END</span> ; ------------------------------------------------------------------------<span>--</span> <span>DECLARE</span> v_nanme varchar2(12); <span>BEGIN</span> v_nanme:=<span>'12312'</span>; hello1(v_nanme);로그인 후 복사
补充:sqlplus中执行含有输出参数为游标的存储过程
实例6:
sqlplus创建存储过程,使用如下:
<span>SQL</span>><span>create</span> <span>or</span> replace <span>procedure</span> test1(rcursor <span>out</span> sys_refcursor) <span>as</span> <span>begin</span> <span>open</span> rcursor <span>for</span> <span>select</span> decode(row_number() <span>over</span>(partition <span>by</span> deptno <span>order</span> <span>by</span> ename), 1, deptno, <span>null</span>) deptno, t.ename <span>from</span> scott.emp t; <span>end</span>; /
--使用sqlplus执行上面创建的带有游标输出参数的存储过程
<span>SQL</span>> var cur refcursor <span>SQL</span>> <span>exec</span> test1(:cur); PL/<span>SQL</span> <span>procedure</span> successfully completed. <span>SQL</span>> <span>print</span> cur; DEPTNO ENAME --------<span>-- ----------</span> 10 CLARK KING MILLER 20 ADAMS FORD JONES SCOTT SMITH 30 ALLEN BLAKE JAMES DEPTNO ENAME --------<span>-- ----------</span> MARTIN TURNER WARD 14 <span>rows</span> selected.

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

뜨거운 주제











Oracle 테이블 스페이스 크기를 쿼리하려면 다음 단계를 따르십시오. 쿼리를 실행하여 테이블 스페이스 이름을 결정하십시오. 쿼리를 실행하여 테이블 스페이스 크기를 쿼리하십시오. sum (bytes)을 total_size, sum (bytes_free)으로 sum (bytes_free), sum (bytes) - sum (bytes_free)으로 dba_data_fices where tablespace_.

데이터 가져 오기 방법 : 1. SQLLOADER 유틸리티 사용 : 데이터 파일 준비, 제어 파일 작성 및 SQLLOADER 실행; 2. IMP/EXP 도구를 사용하십시오 : 데이터 내보내기, 데이터 가져 오기. 팁 : 1. 빅 데이터 세트에 권장되는 SQL*로더; 2. 대상 테이블이 존재해야하고 열 정의가 일치해야합니다. 3. 가져 오기 후에는 데이터 무결성을 확인해야합니다.

Oracle 설치 실패에 대한 방법 제거 : Oracle Service를 닫고 Oracle Program 파일 및 레지스트리 키 삭제, Oracle 환경 변수를 제거하고 컴퓨터를 다시 시작하십시오. 제거되지 않으면 Oracle 범용 제거 도구를 사용하여 수동으로 제거 할 수 있습니다.

Oracle은 여러 가지 중복 제거 쿼리 방법을 제공합니다. 별개의 키워드는 각 열에 고유 한 값을 반환합니다. 그룹 별 조항은 결과를 그룹화하고 각 그룹에 대해 비 반복 값을 반환합니다. 고유 한 키워드는 고유 한 행만 포함 된 인덱스를 만드는 데 사용되며 인덱스 쿼리는 자동으로 망상됩니다. row_number () 함수는 고유 한 숫자를 할당하고 1 행 만 포함하는 결과를 필터링합니다. 최소 () 또는 max () 함수는 숫자 열의 비 반복 값을 반환합니다. 교차 연산자는 두 결과 세트의 공통 값을 반환합니다 (중복 없음).

Oracle 테이블 작성에는 다음 단계가 필요합니다. 테이블 작성 구문을 사용하여 테이블 이름, 열 이름, 데이터 유형, 제약 조건 및 기본값을 지정하십시오. 테이블 이름은 간결하고 설명 적이어야하며 30자를 초과해서는 안됩니다. 열 이름은 설명 적이어야하며 데이터 유형은 열에 저장된 데이터 유형을 지정합니다. NOT NULL 제약 조건은 열에서 NULL 값이 허용되지 않도록하고 기본 조항은 열의 기본값을 지정합니다. 테이블의 고유 한 레코드를 식별하기위한 주요 주요 제약. 외국 키 제약 조건은 테이블의 열이 다른 테이블의 기본 키를 지칭하도록 지정합니다. 기본 키, 고유 한 제약 조건 및 기본값이 포함 된 샘플 테이블 학생의 생성을 참조하십시오.

Oracle에서 인스턴스 이름을 보는 세 가지 방법이 있습니다. 명령 줄에 명령. "show instance_name"을 사용하십시오. sql*plus의 명령. 운영 체제의 작업 관리자, Oracle Enterprise Manager 또는 운영 체제를 통해 환경 변수 (Linux의 Oracle_Sid)를 확인하십시오.

Oracle View 암호화를 사용하면보기에서 데이터를 암호화 할 수 있으므로 민감한 정보의 보안을 향상시킬 수 있습니다. 단계에는 다음이 포함됩니다. 1) 마스터 암호화 키 생성 (MEK); 2) 암호화 된 뷰 생성, 암호화 할보기 및 MEK를 지정하는 것; 3) 사용자가 암호화 된보기에 액세스하도록 승인합니다. 암호화 된 뷰 작동 방식 : 사용자가 암호화 된보기를 쿼리 할 때 Oracle은 MEK를 사용하여 데이터를 해독하여 공인 사용자 만 읽기 쉬운 데이터에 액세스 할 수 있도록합니다.

데이터베이스 문자 세트를 확인하여 데이터와 일치하는지 확인하여 Oracle Garbled 문제를 해결할 수 있습니다. 클라이언트 문자 세트를 데이터베이스와 일치하도록 설정하십시오. 데이터베이스 문자 세트와 일치하도록 데이터 변환 또는 열 문자 세트를 수정하십시오. 유니 코드 문자 세트를 사용하고 멀티 바이트 문자 세트를 피하십시오. 데이터베이스 및 클라이언트의 언어 설정이 올바른지 확인하십시오.
