一、介绍

函数(Function)为一命名的存储程序,可带参数(有无均可),有返回值

函数和过程的结构类似,但必须有一个RETURN子句,用于返回函数值。

函数说明要指定函数名、返回值的类型,以及参数类型等,如CREATE OR REPLACE FUNCTION access_hel_by_dbws(username in varchar2) RETURN VARCHAR2

二、语法

CREATE [OR REPLACE] FUNCTION 函数名(参数列表) -- 参数类型与函数返回值类型不用标注类型大小,即varchar2即可
RETURN 函数值类型
AS
PLSQL子程序体;

三、简单例子:计算两个数字的和

3.1、函数定义

CREATE OR REPLACE FUNCTION add_numbers(d1 in number, d2 in number) -- 函数声明,包括名称、参数名称及类型
return number -- 返回值类型声明
as -- 或者写作is,均可
begin -- begin与end中间为pl sql 代码块,可执行查询、插入、更新、删除操作
return d1+d2; -- return子句返回两数字之和
end;
如何执行上述代码建立函数?当做sql语句在sql window(pl sql)窗口里执行即可,或者其他客户端相应执行sql语句的窗口

3.2、调用方式

(1)、执行sql查询语句

1
select add_numbers(1,2) from dual;

(2)、执行pl sql代码块

以pl sql客户端为例,打开sql window,在sql栏里粘贴如下代码,在output一栏里即可看到结果

1
2
3
4
5
6
declare -- declare部分可有可无,若无变量需要声明,则可去掉,只留begin、end
sum_ number;
begin
sum_:=add_numbers(1,2);
dbms_output.put_line('sum is:' || sum_);
end;
截图如下:

(3)、在触发器,存储过程中均可调用函数,即在pl sql代码块范围内、sql语句中均可调用。

(4)、在java程序中调用存储函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
package zxn.function.test;
 
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
 
public class Test {
public static void main(String[] args) throws SQLException {
/**
* jdbc方式连接oracle数据库
*/
Connection connection = null;
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
String url = "jdbc:oracle:thin:@localhost:1521:orcl";
String user = "sys as sysdba";
String pwd = "orcl";
connection = DriverManager.getConnection(url,user,pwd);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
/** 调用oracle函数 */
CallableStatement callableStatement=connection.prepareCall("{?=call add_numbers(?, ?)}");
/** 设置第一个问号占位符的类型,第一个问号表示函数输出结果 ,顺序从1开始 */
callableStatement.registerOutParameter(1, oracle.jdbc.OracleTypes.NUMERIC);
/** 设置第二个参数与第三个参数的类型及值,即设置两个加数 */
callableStatement.setDouble(2, 3.6566);
callableStatement.setDouble(3, 3);
/** 执行存储函数 */
callableStatement.execute();
/** 得到函数执行结果 */
System.out.println(callableStatement.getString(1));
}
}

4、复杂例子:在存储函数中使用UTL_DBWS调用webservice

4、1前提是oracle数据库导入utl_dbws包,并能正常使用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
CREATE OR REPLACE FUNCTION access_hello_by_dbws(username in varchar2, age in integer)
RETURN VARCHAR2
AS
l_service UTL_DBWS.service; -- 定义service服务
l_call UTL_DBWS.call; -- 定义调用对象
l_wsdl_url VARCHAR2(32767);
l_namespace VARCHAR2(32767);
l_service_qname UTL_DBWS.qname;
l_port_qname UTL_DBWS.qname;
l_operation_qname UTL_DBWS.qname;
request sys.XMLTYPE; -- 响应xml
response sys.XMLTYPE; -- 请求xml
 
BEGIN
l_wsdl_url := 'http://localhost:7878/hello?wsdl'; -- webservice服务的wsdl地址
l_namespace := 'http://test.xiangnan.it/'; -- targetNamespace属性的值,最后的/不能少,否则报...does not contains port...
 
l_service_qname := UTL_DBWS.to_qname(l_namespace, 'HelloWorldService'); -- service节点name属性值
l_port_qname := UTL_DBWS.to_qname(l_namespace, 'HelloWorldPort'); -- port节点name属性值
l_operation_qname := UTL_DBWS.to_qname(l_namespace, 'hello'); -- operation节点name属性值
 
l_service := UTL_DBWS.create_service ( -- 根据wsdl与service name创建service对象
wsdl_document_location => URIFACTORY.getURI(l_wsdl_url),
service_name => l_service_qname);
 
l_call := UTL_DBWS.create_call ( -- 创建调用对象
service_handle => l_service,
port_name => l_port_qname,
operation_name => l_operation_qname);
 
sys.utl_dbws.set_target_endpoint_address(l_call, 'http://localhost:7878/hello'); -- 设置调用对象的endpoint,也可不设置,
-- 该属性可通过soap UI查看
 
request := sys.XMLTYPE('<test:hello xmlns:test="http://test.xiangnan.it/"> -- 拼接request,可通过soap ui查看request进行拼接
<arg0>'||username||'</arg0> -- ||||之间为定义的变量
<arg1>'||age||'</arg1>
</test:hello>
');
 
response := utl_dbws.invoke(l_call, request); -- 发出请求,并接受响应
 
UTL_DBWS.release_call (call_handle => l_call); -- 释放call对象
UTL_DBWS.release_service (service_handle => l_service); -- 释放service对象
-- 获取响应值,可通过soap ui查看response内容
return response.extract('/ns2:helloResponse/return/text()', ' xmlns:ns2="http://test.xiangnan.it/"').getstringval();
EXCEPTION
WHEN OTHERS THEN
dbms_output.put_line(sqlerrm); -- 输出错误
return sqlerrm;
END;

4.2、测试

在pl sql 中functions列表下面,选中定义的函数,右键点击,选择Test,如图:

输入对应的测试参数,得到结果,如图:

本文来自:http://www.2cto.com/database/201403/288437.html

oracle之FUNCTION拙见的更多相关文章

  1. oracle的function和procedure返回值给shell

    本文演示两个关于如何在shell中调用oracle的function和procedure,并将返回值返回给shell. 1.首在package中创建function和procedure,脚本如下: G ...

  2. Oracle Table Function

    Oracle Table Function在Oracle9i时引入.完美的兼容了view和存储过程的长处: 应用举例: 1.Table()函数: set feedback off create or ...

  3. Oracle SYS_CONTEXT Function

    Version 11.1   Actions As SYS Note: USERENV is an Oracle provided namespace that describes the curre ...

  4. Oracle 函数function之返回结果集

    工作中常需要经过一段复杂逻辑处理后,得出的一个结果集.并能够将这个结果集作为一个表看待,去进行关联查询 我一般采用建立函数function的方式来处理. --创建包,声明function和typeCR ...

  5. Oracle函数function

    --function /* 函数是有返回值.-只能有一个返回值. 语法 Create or replace func1(参数) Return varchar2 As Pl/sql块 Return 'J ...

  6. Oracle存储过程function语法及案例

    create or replace function F01_SX03_SUM(statdate varchar2, code varchar2, para varchar2) RETURN numb ...

  7. Oracle的function

    写在这里,以便于以后忘记格式后可以查询. CREATE OR REPLACE FUNCTION TEMP_FUNC_WYL(PI_AAA100 VARCHAR2, PI_AAA102 VARCHAR2 ...

  8. Oracle 函数 Function

    定义 函数用于计算和返回一个结果值,把经常需要进行的计算写成函数,函数的调用是表达式的一部分.     函数与过程在创建的形式上有些相似,也是编译后放在内存中供用户使用.     函数必须有一个返回值 ...

  9. Oracle Date Function 讲解和事例

    1 year=1*12 months 1 day=24 hours=24*(1*60mins)=24*60*(1*60 seconds) 1 week =7 days 注意: 黑色字体是 oracle ...

随机推荐

  1. 2019/10/17 CSP模拟 总结

    T1 补票 Ticket 没什么好说的,不讲了 T2 删数字 Number 很后悔的是其实考场上不仅想出了正解的方程,甚至连优化都想到了,却因为码力不足只打了\(O(n^2)\)暴力,甚至还因为细节挂 ...

  2. iOS之UIButton的normal和selected状态切换

    1.问题? 改变播放器按钮状态,发现从selected切回到normal状态时候,中间会切换normal-selected-normal的图片? 2.原因…… normal-->selected ...

  3. ssh 与服务器保持连接

    直接改客户端,服务器端不应该更改. sudo vi /etc/ssh/ssh_config # 或 ~/.ssh/config TCPKeepAlive=yes # Client每隔 60 秒发送一次 ...

  4. PHP实现图片的汉明码提取与降维

    作者感言:数学不好,遇到算法问题分分钟狗带,毫无转寰的余地-_-||| 最近心血来潮,看了相似图片的搜索,最最最初级的方法即提取汉明码,之后匹配汉明距离.当然,在数以亿计的汉明码中,要筛出需要的图片, ...

  5. 设定计算属性setter

    <!DOCTYPE html> <html lang="zh"> <head> <title></title> < ...

  6. selenium 三种断言以及异常类型

    selenium 提供了三种模式的断言:assert .verify.waitfor Assert 失败时,该测试将终止. Verify 失败时,该测试将继续执行,并将错误记入日显示屏 .也就是说允许 ...

  7. Hibernate调用Oracle的存储过程

    众所周知,当过多的使用存储过程,触发器等 数据库方言相关的应用时,应用程序的移植性会变差,特别是在Hibernate中使用这些,简直是讽刺,但是当今中国又有哪家公司做项目会关心应用程序的移植性呢? 现 ...

  8. vue:使用不同参数跳转同一组件,实现动态加载图片和数据,以及利用localStorage和vuex持久化数据

    需求:通过不同的参数复用同一组件,实现动态加载数据和图片,同时,在页面刷新时,图片依旧可以加载成功. 过程出现的bug和问题: 1.使用params传参后,再次刷新页面,参数丢失导致数据无法再次加载 ...

  9. [转]Visual Studio 2010单元测试(1)--运行和定义普通单元测试

    Visual Studio 2010 运行和定义单元测试 在VS2010中,单元测试的功能很强大,使得建立单元测试和编写单元测试代码,以及管理和运行单元测试都变得简单起来,通过私有访问器可以对私有方法 ...

  10. 史上最直接小白式的Sourcetree的分支创建与合并

    一.Sourcetree简单介绍通过Git可以进行对项目的版本管理,但是如果直接使用Git的软件会比较麻烦,因为是通过一条一条命令进行操作的. Sourcetree则可以与Git结合,提供图形界面,使 ...