(Oracle管理)SQL中调用ORACLE存储过程
- 格式:doc
- 大小:36.11 KB
- 文档页数:6
O r a c l e存储过程学习目录Oracle存储过程基础知识商业规则和业务逻辑可以通过程序存储在Oracle中,这个程序就是存储过程。
存储过程是SQL, PL/SQL, Java 语句的组合,它使你能将执行商业规则的代码从你的应用程序中移动到数据库。
这样的结果就是,代码存储一次但是能够被多个程序使用。
要创建一个过程对象 procedural object ,必须有 CREATE PROCEDURE 系统权限。
如果这个过程对象需要被其他的用户schema 使用,那么你必须有 CREATE ANY PROCEDURE 权限。
执行procedure 的时候,可能需要excute权限。
或者EXCUTE ANY PROCEDURE 权限。
如果单独赋予权限,如下例所示:grant execute on MY_PROCEDURE to Jelly调用一个存储过程的例子:execute MY_PROCEDURE 'ONE PARAMETER' ;存储过程 PROCEDURE 和函数 FUNCTION 的区别。
function有返回值,并且可以直接在Query中引用function和或者使用function的返回值。
本质上没有区别,都是 PL/SQL 程序,都可以有返回值。
最根本的区别是:存储过程是命令, 而函数是表达式的一部分。
比如:select max NAME FROM但是不能 exec max NAME 如果此时max是函数。
PACKAGE是function,procedure,variables 和sql 语句的组合。
package允许多个procedure使用同一个变量和游标。
创建 procedure的语法:Sql 代码:可以使用 create or replace procedure 语句, 这个语句的用处在于,你之前赋予的excute 权限都将被保留。
IN, OUT, IN OUT用来修饰参数。
存储过程是由流控制和SQL语句书写的过程,这个过程经编译和优化后存储在数据库服务器中,FienReport使用时只要调用即可。
调用Oracle数据库存储过程主要有两步:第一步,定义存储过程;第二步,调用存储过程。
下面以一个具体的实例来学习如何使用FineReport调用Oracle数据库存储过程的。
第一步,Oracle定义存储过程StScroe是Oracle数据库中的一张表,其中记录了学生的成绩信息,表结构如下:表:记录了学生的成绩信息定义返回列表的存储过程——由于oracle存储过程没有返回值,它的所有返回值都是通过out参数来替代的,列表同样也不例外,但由于是集合,所以不能用一般的参数,必须要用pagkage了,所以定义存储过程要分两部分:1.建立一个程序包,如下:CREATE OR REPLACE PACKAGE TESTPACKAGE ASTYPE Test_CURSOR IS REF CURSOR;END TESTPACKAGE;2.建立存储过程,存储过程为:CREATE OR REPLACE PROCEDURE p_STSCORE(Class in varchar2,p_CURSOR out TESTPACKAGE.Test_CURS OR) ISBEGINOPEN p_CURSOR FOR SELECT * FROM FR.STSCORE where STSCORE.ClassNo=Class;END p_STSCORE;第二步,调用存储过程1.启动FineReport设计器,右击数据源面板,选择私有数据源,弹出私有数据源对话框。
2.点击增加按钮,新建一个私有数据源,名为ds1,数据库选择为Oracle数据源,查询类型为存储过程,在sql文本框中写如下语句调用存储过程:{call fr.p_stscore('[?Class|Class1?]',?)}在sql文本框中写下调用存储过程语句3.点击预览按钮,可以预览查询到的数据,如下所示:预览查询到的数据至此,FineReport设计器成功调用Oracle数据库存储过程,您可以根据报表需求随心所欲地设计报表样式了。
oracle存储过程的用法一、存储过程概述存储过程是在数据库中预先编译好的SQL语句集合,它可以在数据库中作为一个独立的对象存在,并由数据库管理系统执行。
存储过程具有可重复使用、可编译优化、可嵌套调用等优点,是数据库开发中常用的一种技术手段。
二、存储过程的创建要创建存储过程,需要使用Oracle数据库的SQL开发工具(如SQLDeveloper)或命令行工具(如SQL*Plus)。
创建存储过程的语法如下:```sqlCREATEPROCEDUREprocedure_name[parameter_list][IS|AS]block_of_code[LANGUAGE][sql][EXECUTEIMMEDIATE]SQL_CODE```其中,`procedure_name`是存储过程的名称,`parameter_list`是可选的参数列表,`block_of_code`是存储过程的主体代码,`LANGUAGE`指定存储过程的编程语言(如PL/SQL),`EXECUTEIMMEDIATE`用于执行动态SQL代码。
三、存储过程的参数存储过程的参数可以是输入参数、输出参数或输入/输出参数。
输入参数表示从调用方传递给存储过程的值,输出参数表示存储过程的结果值返回给调用方,而输入/输出参数则同时具有输入和输出功能。
在存储过程中,可以使用SQL数据类型(如VARCHAR2、NUMBER、DATE等)或Oracle特有的数据类型(如RAW、BLOB等)来定义参数。
同时,还可以使用PL/SQL的数据类型(如RAW、BLOB、CLOB等)来定义存储过程的局部变量和输出参数。
四、存储过程的调用要调用存储过程,需要使用EXECUTE语句或调用对象的方法。
例如:```sqlEXECUTEprocedure_name(parameter1,parameter2);```或```vbnetprocedure_object.procedure_method();```其中,`procedure_name`是存储过程的名称,`parameter1`和`parameter2`是传递给存储过程的参数值。
SQL Server调用Oracle的存储过程收藏原文如下:通过SQL Linked Server 执行0rac 1 e存储过程小结1举例我们可以通过下面的方法在SQL Server中通过Linked Server来执行Oracle存储过程。
(1)Oracle PackagePACKAGE Test PACKAGE ASTYPE t_t is TABLE of VARCHAR2(30)INDEX BY BINARY,INTEGER;PROCEDURE Test procedure1(p BATCH」D IN VARCHAR2,p__Number IN number,P.MSG OUT t_t.p MSG1 OUT t_t);END Test PACKAGE;PACKAGE BODY Test PACKAGE ASPROCEDURE Test procedure1(p BATCH一ID IN VARCHAR2,p Number IN number,P.MSG OUT t_t,p MSG1 OUT t_t)ASBEGINp. MSGp. MSG(2): = ,b,;p. MSG(3)=a‘;p MSGl(l):= Qbc‘;RETURN;MIT;EXCEPTIONWHEN OTHERS THENROLLBACK;END Test procedure1;END Test PACKAGE;(2)在SQL Server中通过Linked Server 来执行Oracle 存储过程declare BatchID nvarchar (40)declare QueryStr nvarchar (1024)declare StatusCode nvarchar(100)declare sq1 nvarchar(1024)set BatchID=,AM*SET QueryStr=, {CALL GSN. Test_PACKAGE. Test_procedurel(* * *1,+BatchID+,1'".八'‘4’'''.{resultset 3. p_MSG}.{resultset 1, p_ MSG1})}1(3)执行结果(a)select sql=r SELECT StatusCode=p. msg FROM OPENQUERY (HI4DB__MS,r11-Query Str+''')'exec sp executesql sql,N f StatusCode nvarchar(100) output*,StatusCode outpu tprint StatusCode答案:StatusCode=, a'(b) select sql=f SELECT top 3 StatusCode=p_msg FROM OPENQUERY (HI4DB MS,-QueryStr+,,F)rexec sp_executesql sql,N1StatusCode nvarchar(100) output *.StatusCode outpu print StatusCode答案:StatusCode=, a(c)select sql=f SELECT top 2 StatusCode=p_msg FROM OPENQUERY (HI4DB MS,1r r -QueryStr+,,f)rexec sp_executesql sql.N1StatusCode nvarchar(100) output r.StatusCode outpu tprint StatusCode答案:StatusCode=, b'(d)select sql=r SELECT top 1 StatusCode=p_msg FROM OPENQUERY (HI4DB MS,1'r-QueryStr+,,f)rexec sp executesql sqlStatusCode nvarchar(100) output1,StatusCode outpu print StatusCode答案:StatusCode二'c(e)SET QueryStr=,{CALL GSN. Test.PACKAGE. Test procedure1C11f,+BatchID+,11 *r / 1''4'' '' • {resultset 1, p. MSG1}. {resultset 3. p_MSG})}'----------------------------------- (注意这里p_MSG1 和P MSG交换次序了)EXEC(r SELECT p…msgl FROM OPENQUERY (HI4DB MS/r,-QueryStr+,r1)r) select sql=r SELECT StatusCode=p_msgl FROM OPENQUERY (HI4DB MS/r,-QuerySexec sp executesql sql,N*StatusCode nvarchar(100) output*,StatusCode outpuprint StatusCode答案:StatusCode=" abc*2上述使用方法的条件(1)Link Server 要使用Microsoft 的Driver (Microsoft OLE DB Provider fo r Oracle)(2)Oracle Package中的Procedure的返回参数是Table类型,目前table只试成功一个栏位。
Oracle (存储过程、存储函数、⽤程序调⽤)指存储在数据库中的供所有⽤户程序带哦⽤的⼦程序(PL/SQL )叫存储过程(不能返回值)、存储函数(可以通过return 语句返回值)1、存储过程为了完成特定功能的SQL 语句集,经编译后存储在数据库中。
(1)新建:(2)书写存储过程的代码:(3)编译运⾏代码:(4)调⽤存储过程:2、存储函数create or replace procedure raiseSalary(eno in number)ispsal emp.sal %type;beginselect sal into psal from emp where empno=eno;update emp set sal= sal + 100 where empno = eno ;dbms_output.put_line('前:'||psal||'后:'||(psal+100));end raiseSalary;存储函数与存储过程的结构类似,但是必须有⼀个return ⼦句,⽤于返回函数值。
(1)创建⼀个存储函数:(2)书写代码:(3)右键选择test:3、存储过程和存储函数的OUT(1)创建存储过程:(2)书写程序:查询员⼯的信息(3)测试结果:create or replace function queryEmpIncome(eno in number)return numberispsal emp.sal %type;pcomm m %type;beginselect sal,comm into psal,pcomm from emp where empno=eno;return psal*12+nvl(pcomm,0);end queryEmpIncome;create or replace procedure queryEmpInfeno(eno in number,pename out varchar2,psal out number,pjob out varchar2)isbeginselect ename,sal,job into pename,psal,pjob from emp where empno=eno; end queryEmpInfeno;4、java程序调⽤存储过程和存储函数(1)先在虚拟机中找到需要导⼊的jar包并进⾏导⼊:(2)书写⼀个⼯具类:package pers.zhb.utils;import java.sql.*;public class JDBCUtils {private static String driver = "oracle.jdbc.OracleDriver";private static String url = "jdbc:oracle:thin:@192.168.125.129:1521/orcl"; private static String user = "scott";private static String password = "tiger";static{try {Class.forName(driver);} catch (ClassNotFoundException e) {throw new ExceptionInInitializerError(e);}}public static Connection getConnection(){try {return DriverManager.getConnection(url, user, password);} catch (SQLException e) {e.printStackTrace();}return null;}public static void release(Connection conn, Statement st, ResultSet rs){ if(rs != null){try {rs.close();} catch (SQLException e) {e.printStackTrace();}finally{rs = null;}}if(st != null){try {st.close();} catch (SQLException e) {e.printStackTrace();}finally{st = null;}}if(conn != null){try {conn.close();} catch (SQLException e) {e.printStackTrace();}finally{conn = null;}}}}(3)创建测试类,调⽤存储过程和存储函数:public class Test {public void testProcedure(){String sql = "{call raiseSalary(?,?,?,?)}";Connection conn = null;CallableStatement call = null;try {conn = JDBCUtils.getConnection();call = conn.prepareCall(sql);call.setInt(1,7839);call.registerOutParameter(2, OracleTypes.VARCHAR); call.registerOutParameter(3, OracleTypes.NUMBER); call.registerOutParameter(4, OracleTypes.VARCHAR); call.execute();String name = call.getString(2);double sal = call.getDouble(3);String job = call.getString(4);System.out.println(name+"\t"+sal+"\t"+job);} catch (Exception e) {e.printStackTrace();}finally{JDBCUtils.release(conn, call, null);}}public void testFunction(){String sql = "{?=call queryEmpIncome(?)}";Connection conn = null;CallableStatement call = null;try {conn = JDBCUtils.getConnection();call = conn.prepareCall(sql);call.registerOutParameter(1, OracleTypes.NUMBER); call.setInt(2, 7839);call.execute();double income = call.getDouble(1);System.out.println(income);} catch (Exception e) {e.printStackTrace();}finally{JDBCUtils.release(conn, call, null);}}public static void main(String [] args){Test test=new Test();test.testFunction();}}。
oracle sql查询存储过程内容Oracle SQL查询存储过程内容在Oracle数据库中,存储过程是一种预编译的数据库对象,用于封装一系列的SQL语句和业务逻辑。
当我们需要查询存储过程的内容时,可以通过以下方式实现:1. 使用Oracle SQL开发工具Oracle SQL开发工具如SQL Developer、Toad等,提供了直接查询数据库对象的功能。
通过连接到相应的数据库,我们可以执行以下步骤:•打开SQL开发工具并连接到数据库。
•在数据库导航栏中选择存储过程所在的模式(Schema)。
•展开“存储过程”(或类似的选项)文件夹,找到目标存储过程。
•右键单击存储过程,并选择“查看”选项。
•在弹出的窗口中,可以查看到存储过程的代码或源码。
2. 使用SQL查询系统表Oracle数据库提供了一些系统表,存储了数据库对象的元数据信息。
我们可以通过查询这些系统表来获取存储过程的内容。
以下是一些常用的系统表和他们的用途:•ALL_OBJECTS:包含了数据库中所有的对象信息,包括存储过程。
•ALL_SOURCE:存储了数据库中所有对象的源码信息,包括存储过程的代码。
•ALL_PROCEDURES:记录了所有存储过程的详细信息,包括存储过程名称、所属模式等。
通过执行类似以下的SQL查询语句,我们可以获取存储过程的内容:SELECT textFROM all_sourceWHERE object_type = 'PROCEDURE'AND owner = 'SCHEMA_NAME'AND name = 'PROCEDURE_NAME';请注意将上述查询语句中的’SCHEMA_NAME’和’PROCEDURE_NAME’替换为实际的模式名称和存储过程名称。
3. 使用DBMS_METADATA包Oracle数据库提供了一个名为DBMS_METADATA的强大的包,它可以用于获取数据库对象的元数据信息。
oracle调用存储过程的sql语句
Oracle数据库中,调用存储过程可以使用SQL语句,具体步骤如下:
1. 创建存储过程
先在数据库中创建存储过程。
例如,创建一个名为'my_proc'的存储过程,代码如下:
CREATE OR REPLACE PROCEDURE my_proc
IS
BEGIN
-- 存储过程的具体操作,可以包括SQL语句、PL/SQL代码等 ...
END;
2. 调用存储过程
在SQL语句中调用存储过程,可以使用如下语句:
BEGIN
my_proc; -- 调用存储过程
END;
调用存储过程时,可以传入参数。
例如,假设存储过程需要传入一个参数'param1',可以使用如下语句:
BEGIN
my_proc(param1); -- 调用存储过程,并传入参数
END;
在SQL语句中调用存储过程时,还可以将存储过程的返回值赋值给变量。
例如,假设存储过程返回一个数值类型的值'result',可以使用如下语句:
DECLARE
result NUMBER;
BEGIN
result := my_proc; -- 调用存储过程,并将返回值赋值给result变量
END;
以上是Oracle调用存储过程的SQL语句的简要介绍。
在实际使用中,需要根据具体情况灵活应用。
SQL中调用ORACLE存储过程在SQL中调用Oracle存储过程是一种常见的操作,可以通过以下步骤实现:1.创建存储过程:首先,在Oracle数据库中创建存储过程。
存储过程是一段预编译的代码块,可以在需要的时候被调用。
它可以接收参数并执行一系列的SQL语句。
例如,我们创建一个简单的存储过程,命名为"GET_EMPLOYEE",该存储过程接收一个参数"EMPLOYEE_ID",根据该参数查询并返回员工的信息。
```sqlCREATEORREPLACEPROCEDUREGET_EMPLOYEEEMPLOYEE_IDINNUMBER,EMPLOYEE_NAMEOUTVARCHAR2,EMPLOYEE_DEPARTMENTOUTVARCHAR2,EMPLOYEE_SALARYOUTNUMBERABEGINSELECTNAME,DEPARTMENT,SALARYINTOEMPLOYEE_NAME,EMPLOYEE_DEPARTMENT,EMPLOYEE_SALARYFROMEMPLOYEESWHEREID=EMPLOYEE_ID;END;/```上述代码中,我们定义了一个存储过程"GET_EMPLOYEE",它接收一个参数"EMPLOYEE_ID",以及三个输出参数"EMPLOYEE_NAME"、"EMPLOYEE_DEPARTMENT"和"EMPLOYEE_SALARY"。
在存储过程中,我们使用"SELECTINTO"语句将查询结果赋值给输出参数。
2.调用存储过程:一旦存储过程创建成功,就可以通过SQL语句来调用它。
```sqlDECLAREEMP_NAMEVARCHAR2(50);EMP_DEPTVARCHAR2(50);EMP_SALNUMBER;BEGINGET_EMPLOYEE(1001,EMP_NAME,EMP_DEPT,EMP_SAL);--执行后,EMP_NAME、EMP_DEPT和EMP_SAL将分别包含员工1001的姓名、部门和薪水信息END;/```在上述代码中,我们使用DECLARE块定义了三个变量"EMP_NAME"、"EMP_DEPT"和"EMP_SAL",这些变量分别用来存储存储过程的输出参数。
Oracle中存储过程的使⽤⼀、什么是存储过程:存储过程(Stored Procedure )是⼀组为了完成特定功能的SQL 语句集,经编译后存储在数据库中。
⽤户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执⾏它。
存储过程是数据库中的⼀个重要对象,任何⼀个设计良好的数据库应⽤程序都应该⽤到存储过程。
存储过程是由流控制和SQL 语句书写的过程,这个过程经编译和优化后存储在数据库服务器中,应⽤程序使⽤时只要调⽤即可。
在ORACLE 中,若⼲个有联系的过程可以组合在⼀起构成程序包。
其优点如下:1. 存储过程和函数以命名的数据库对象形式存储于数据库当中。
存储在数据库中的优点是很明显的,因为代码不保存在本地,⽤户可以在任何客户机上登录到数据库,并调⽤或修改代码。
2. 存储过程和函数可由数据库提供安全保证,要想使⽤存储过程和函数,需要有存储过程和函数的所有者的授权,只有被授权的⽤户或创建者本⾝才能执⾏存储过程或调⽤函数。
3. 存储过程和函数的信息是写⼊数据字典的,所以存储过程可以看作是⼀个公⽤模块,⽤户编写的PL/SQL程序或其他存储过程都可以调⽤它(但存储过程和函数不能调⽤PL/SQL程序)。
⼀个重复使⽤的功能,可以设计成为存储过程。
4. 像其他⾼级语⾔的过程和函数⼀样,可以传递参数给存储过程或函数,参数的传递也有多种⽅式。
存储过程可以有返回值,也可以没有返回值,存储过程的返回值必须通过参数带回;函数有⼀定的数据类型,像其他的标准函数⼀样,我们可以通过对函数名的调⽤返回函数值。
5. 存储过程和函数需要进⾏编译,以排除语法错误,只有编译通过才能调⽤。
⼆、创建存储过程:create [or replace] procedure 存储过程名 [(输⼊、输出参数、in/out模式参数)]is/asbeginsentences;[exceptionsentences;]end 存储过程名;【例1】⼀个没有参数的存储过程:SQL>set serveroutput onSQL> create or replace procedure pro_no_par is2 begin3 update emp set sal=sal+800 where id=3;4 commit;5 dbms_output.put_line('⼯资已经调整!!');6 end pro_no_par;7 /SQL> execute pro_no_par;⼯资已经调整!!PL/SQL 过程已成功完成。
oracle存储过程调⽤⽅式Oracle存储过程包含三部分:过程声明,执⾏过程部分,存储过程异常。
Oracle存储过程可以有⽆参数存储过程和带参数存储过程。
⼀、⽆参程序过程语法1 create or replace procedure NoParPro2 as ;3 begin4 ;5 exception //存储过程异常6 ;7 end;8⼆、带参存储过程实例1 create or replace procedure queryempname(sfindno emp.empno%type) as2 sName emp.ename%type;3 sjob emp.job%type;4 begin5 ....7 exception....14 end;15三、带参数存储过程含赋值⽅式1 create or replace procedure runbyparmeters (isal in emp.sal%type,sname out varchar,sjob in out varchar)2 as icount number;3 begin4 select count(*) into icount from emp where sal>isal and job=sjob;5 if icount=1 then6 ....9 else10 ....12 end if;13 exception14 when too_many_rows then15 DBMS_OUTPUT.PUT_LINE('返回值多于1⾏');16 when others then17 DBMS_OUTPUT.PUT_LINE('在RUNBYPARMETERS过程中出错!');18 end;19四、在Oracle中对存储过程的调⽤过程调⽤⽅式⼀1 declare2 realsal emp.sal%type;3 realname varchar(40);4 realjob varchar(40);5 begin //存储过程调⽤开始6 realsal:=1100;7 realname:='';8 realjob:='CLERK';9 runbyparmeters(realsal,realname,realjob); --必须按顺序10 DBMS_OUTPUT.PUT_LINE(REALNAME||' '||REALJOB);11 END; //过程调⽤结束12过程调⽤⽅式⼆1 declare2 realsal emp.sal%type;3 realname varchar(40);4 realjob varchar(40);5 begin //过程调⽤开始6 realsal:=1100;7 realname:='';8 realjob:='CLERK';9 runbyparmeters(sname=>realname,isal=>realsal,sjob=>realjob); --指定值对应变量顺序可变10 DBMS_OUTPUT.PUT_LINE(REALNAME||' '||REALJOB);11 END; //过程调⽤结束12。
oracle过程调用方法【实用版4篇】目录(篇1)I.引言A.介绍B.本文目的II.Oracle过程调用方法A.存储过程1.定义2.创建存储过程3.调用存储过程B.函数1.定义2.创建函数3.调用函数C.游标1.定义2.使用游标3.遍历游标III.结论A.总结B.对Oracle过程调用方法的评价正文(篇1)Oracle过程调用方法存储过程是预编译的存储函数,可以在数据库中执行一系列SQL语句。
存储过程通常用于执行常见的数据库任务,例如更新数据、插入记录或删除数据。
创建存储过程需要使用Oracle提供的PL/SQL编辑器。
编写存储过程的步骤包括:定义输入参数、处理逻辑、定义输出参数以及返回值。
然后,将存储过程保存到数据库中。
要调用存储过程,只需在SQL*Plus或Java等编程语言中指定存储过程的名称和参数即可。
存储过程的执行将触发SQL语句的执行,并将结果返回给调用者。
除了存储过程,Oracle还提供了函数。
函数类似于存储过程,但具有不同的功能。
函数接受输入参数,执行一系列操作并返回结果。
与存储过程不同,函数的参数不能包含游标、子查询或表连接等复杂的SQL语句。
Oracle还提供了游标,这是一种特殊的对象,可用于遍历结果集中的每一行数据。
游标通常用于查询和检索大型结果集中的数据。
在Java等编程语言中,可以使用游标遍历结果集中的每一行数据,并执行相应的操作。
总之,Oracle提供了多种方法来调用过程。
存储过程和函数可用于执行常见的数据库任务,而游标则用于遍历结果集中的每一行数据。
目录(篇2)I.引言A.介绍本次任务的目的和要求B.简要介绍中文知识类写作助理的工作原理II.或acle过程调用方法的介绍A.简要介绍oracle过程调用方法的概念和背景B.分析oracle过程调用方法的重要性和应用场景C.比较不同版本的oracle过程调用方法的主要区别和特点III.或acle过程调用方法的实现A.详细介绍oracle过程调用方法的实现原理和步骤B.分析实现过程中可能遇到的问题和解决方法C.探讨优化oracle过程调用方法的途径和方法IV.结论A.总结oracle过程调用方法的重要性和应用前景B.指出未来研究和发展的方向和前景正文(篇2)一、引言本次任务的目的和要求是了解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调⽤存储过程的例⼦⼀样。
一直以来,存储过程就是一个心病啊,都不知道到底什么东西。
不过幸好在别人的带领下,战胜了这个恐惧,算是小小的入门了。
(oracle的sql叫做pl-sql,在语法上和m-sql有一些不同的地方。
而且,由于java和Oracle的密切关系,所以oracle较高版本的pl-sql中也出现一些类似于面向对象编程的语法结构。
)现在把我遇到的各种错误列出来,当然我有log,要不然我都记不住了。
1.ORA-00921: unexpected end of SQL command基本sql错误2.bad SQL grammar基本sql错误3.wrong number or types of arguments in call to ***调用存储过程传入的参数不对4.weblogic.jdbc.wrapper.Array_oracle_sql_ARRAY 使用的是weblogic容器提供的ARRAY,不能直接转化成ORACLE的ARRAY,但是可以用java.sql下面的接口。
5. identifier *** must be declared 数据库中没有定义这个名字的存储过程6.ORA-03115: unsupported network datatype or representation 存储过程传入的参数类型不支持在pl-sql中有package,可以用来定义访问变量的自定义类型,但是返回的类型除了游标以外,都不能被外部,如jdbc来访问。
都会提示类型不知道的错误,不管你有没有加上表空间的名字。
而这个时候需要用全局的类型来定义。
全局的类型,主要分为三种:1.create or replacetype obj_1 as object (** number, ** number,** varchar2(36), ** varchar2(150));2.create or replacetype tab_1 as table of obj_1;3.create or replacetype array_1AS VARRAY(21) OF obj_1;这几种类型都可以作为返回值,而且,后两种类型,常常可以以多维数组的形式返回。
PLSQLDeveloper中如何调试oracle的存储过程本文主要介绍如何在PL/SQL Developer中如何调试oracle的存储过程。
1.打开PL/SQL Developer如果在机器上安装了PL/SQL Developer的话,打开PL/SQL Developer界面输入用户名,密码和host名字,这个跟在程序中web.config中配置的完全相同,点击确定找到需要调试的存储过程所在的包(Package bodies),如PACK_ACTIVITY,点击右键,在弹出菜单中选择[查看],得到包中的所有存储过程和他们的代码.2.添加debug信息为了能够单步跟踪存储过程,需要为其所在的包添加debug信息,右键点击需要调试的包,在弹出菜单中选中[添加调试信息].这样就为包体添加了调试信息。
3.调试存储过程现在所有的准备工作都做好了,可以调试跟踪存储过程了。
选择需要调试的存储过程,点击右键,在弹出菜单中选择[测试],进去测试窗口.测试窗口中有为了测试该存储过程自动所产生的代码,当然你也可以自己另外加入和修改代码,对于我们目前只是为了调试存储过程,自动生成的代码已经足够了。
接着按照如下的步骤进行调试。
(1)添加存储过程所需要的参数,我们项目中的大多数存储过程都是需要参数的,参数可以在测试窗口右下部分输入。
如:GetPanNO_New需要一个输入参数v_employeeid,我们输入180,输出参数是mycursor,是查看结果的,不需要输入任何值。
(2)开始调试,点击[调试]菜单->[开始](或者按F9),就进去调试模式了,程序开始停在begin这一行.(3)以后的调试过程跟我们熟悉的的调试过程就一样了:运行(Ctrl+R)单步进入(Ctrl+N)单步跳过(Ctrl+O)单步退出(Ctrl+T)或者点击debug工具条上的按扭:当按Ctrl+N进去存储过程的源代码中后在这个窗口中可以查看过程中的变量值和堆栈。
oracle存储过程调⽤动态sqloracle 存储过程调⽤动态sqlCreationTime--2018年8⽉16⽇11点25分Author:Marydon1.错误实现⽅式--开始时间拼接' 00:00:00'V_SQL := 'select decode(length(' || V_END || '),10,' || 'concat(' || V_END || ', 00:00:00),' || V_END || ') from dual';EXECUTE IMMEDIATE V_SQL; 编译成功,但是存储过程调⽤失败。
2.原因分析 在oracl数据库中,ddl表⽰数据库定义语⾔,即我们平常使⽤的sql语句,声明的sql语句可以直接使⽤拼接字符串进⾏拼接; dml表⽰数据操纵语⾔,声明的sql语句不能再⽤管道符||来动态拼接变量。
3.正确实现⽅式 execute immediate属于dml,dml使⽤sql的规则如下: 声明sql语句 字符串拼接变量时,变量要使⽤占位符来代替,格式为 ":" + "名字",名字随意 调⽤sql语句 使⽤"using"来传递变量,代替占位符,格式为 "using var1,var2,..."V_SQL := 'select decode(length(:v1),10,:v2,:v3) from dual';EXECUTE IMMEDIATE V_SQL INTO V_START USING V_START,V_START || ' 00:00:00',V_START; 结果展⽰:4.测试 ⼊参 出参5.最简单的⽅式 结果如下 另外对于单引号的转义,两个紧挨的单引号相关推荐:。
SQL Server 调用Oracle的存储过程收藏原文如下:通过SQL Linked Server 执行Oracle 存储过程小结1 举例我们可以通过下面的方法在SQL Server中通过Linked Server 来执行Oracle 存储过程。
(1) Oracle PackagePACKAGE Test_PACKAGE ASTYPE t_t is TABLE of VARCHAR2(30)INDEX BY BINARY_INTEGER;PROCEDURE Test_procedure1( p_BATCH_ID IN VARCHAR2,p_Number IN number,p_MSG OUT t_t,p_MSG1 OUT t_t);END Test_PACKAGE;PACKAGE BODY Test_PACKAGE ASPROCEDURE Test_procedure1( p_BATCH_ID IN VARCHAR2,p_Number IN number,p_MSG OUT t_t,p_MSG1 OUT t_t)ASBEGINp_MSG(1):='c';p_MSG(2):='b';p_MSG(3):='a';p_MSG1(1):='abc';RETURN;COMMIT;EXCEPTIONWHEN OTHERS THENROLLBACK;END Test_procedure1;END Test_PACKAGE;(2) 在SQL Server中通过Linked Server 来执行Oracle 存储过程declare @BatchID nvarchar (40)declare @QueryStr nvarchar (1024)declare @StatusCode nvarchar(100)declare @sql nvarchar(1024)set @BatchID='AAA'SET @QueryStr='{CALL GSN. Test_PACKAGE.Test_procedure1('''''+@BatchID +''''',''''4'''',{resultset 3, p_MSG},{resultset 1, p_MSG1})}'(3)执行结果(a)select @sql='SELECT @StatusCode=p_msg FROM OPENQUERY (HI4DB_MS,'' '+@QueryStr+''')'exec sp_executesql @sql,N'@StatusCode nvarchar(100) output',@StatusCod e outputprint @StatusCode答案:@StatusCode=’a’(b)select @sql='SELECT top 3 @StatusCode=p_msg FROM OPENQUERY (HI4DB_MS,'''+@QueryStr+''')'exec sp_executesql @sql,N'@StatusCode nvarchar(100) output',@StatusCod e outputprint @StatusCode答案:@StatusCode=’a’(c)select @sql='SELECT top 2 @StatusCode=p_msg FROM OPENQUERY (HI4DB _MS,'''+@QueryStr+''')'exec sp_executesql @sql,N'@StatusCode nvarchar(100) output',@StatusCod e outputprint @StatusCode答案:@StatusCode=’b’(d)select @sql='SELECT top 1 @StatusCode=p_msg FROM OPENQUERY (HI4DB _MS,'''+@QueryStr+''')'exec sp_executesql @sql,N'@StatusCode nvarchar(100) output',@StatusCod e outputprint @StatusCode答案:@StatusCode=’c’(e)SET @QueryStr='{CALL GSN. Test_PACKAGE.Test_procedure1('''''+@BatchID +''''',''''4'''',{resultset 1, p_MSG1},{resultset 3, p_MSG})}'----(注意这里p_MS G1和p_MSG交换次序了)EXEC('SELECT p_msg1 FROM OPENQUERY (HI4DB_MS,'''+@QueryStr+''')') select @sql='SELECT @StatusCode=p_msg1 FROM OPENQUERY (HI4DB_MS, '''+@QueryStr+''')'exec sp_executesql @sql,N'@StatusCode nvarchar(100) output',@StatusCode outputprint @StatusCode答案: @StatusCode=’abc’2 上述使用方法的条件(1) Link Server要使用Microsoft的Driver(Microsoft OLE DB Provider for Oracl e)(2) Oracle Package中的Procedure的返回参数是Table类型,目前table只试成功一个栏位。
(3) SQL Server的Store Procedure调用Oracle Procedure时,返回参数名字必须和Procedure相同。
3 上述方法的要点(1) 如果要实现“Oracle和SQL Server数据库”之间的Trans处理,则Oracle的Proce dure不要有Commit,rollback等语句,让SQL Server的Store Procedure去控制整个Trans何时commit。
(2) 假如返回参数大于1个,返回参数的次序可以调换,调用时只返回第一个出现的返回参数,如上面的执行结果(e)。
但是输入参数和返回参数的顺序不能调换。
(3) { resultset n, p_MSG1},这里的n,表示返回表的行数。
N可以大于等于实际的行数,但不能小于实际的行数,会报错。
(4) 假如返回表有多行记录,执行select @sql='SELECT @StatusCode=p_msg FROM OPENQUERY (HI4DB_MS, '''+@QueryStr+''')'exec sp_executesql @sql,N'@StatusCode nvarchar(100) output',@StatusCode outputprint @StatusCode, @StatusCode中的值为最后一行记录的值, 如执行结果(a)。
4 动态SQL语句(1)普通SQL语句可以用Exec执行eg: Select * from MCITYExec('select * from MCITY)sp_executesql N'select * from tableName' -- 请注意字符串前一定要加N(2)字段名,表名,数据库名之类作为变量时,必须用动态SQLeg: declare @FielsName varchar(20)declare @sqls nvarchar(1000)set @FielsName = 'CITY'Select @FielsName from MCITY -- 错误Exec('select ' + @FielsName + ' from MCITY ') -- 请注意加号前后的单引号的边上要加空格set @sqls='select ' + @FielsName + ' from MCITY 'exec sp_executesql @sqls当然将字符串改成变量的形式也可declare @s varchar(1000)set @s = 'select ' + @FielsName + ' from MCITY'Exec(@s) -- 成功exec sp_executesql @s -- 此句会报错declare @s Nvarchar(1000) -- 注意此处改为nvarchar(1000)set @s = 'select ' + @fname + ' from from MCITY'Exec(@s) -- 成功exec sp_executesql @s -- 此句正确(3) 输出参数eg: declare @num intdeclare @sqls nvarchar(1000)declare @strTableName nvarchar(55)set @strTableName='MCITY'set @sqls='select count(*) from ' +@strTableNameexec (@sqls)如何能将exec执行的结果存入变量@num中declare @num intdeclare @sqls nvarchar(1000)declare @strTableName nvarchar(55)set @strTableName='MCITY'set @sqls='select @a=count(*) from '+@strTableNameexec sp_executesql @sqls,N'@a int output',@num outputselect @num(注:以上SQL在sv-02,Qservice下测试通过。