Oracle外部函数,在数据库中自定义外部函数

在oracle中可以使用pl/sql来实现一些复杂的功能,同时可以通过自定义的外部函数来实现很多丰富的功能,我们可以基于c/c++来写一些函数,然后把动态链接库放入ORACLE_HOME中方便直接调用。

首先这种实现方法需要依赖于数据库层面的服务extproc,监听器会生成一个extproc进程,然后专门来处理外部函数的调用。

具体的配置可以在$ORACLE_HOME/network/admin下的listener.ora和tnsnames.ora中体现。

一般通过dbca创建的库都会默认配置extproc的部分,可以看到它使用的是ipc协议而不是tcp协议。

样例如下:

listener.ora

LIST=

(DESCRIPTION=

(ADDRESS_LIST=

(ADDRESS=(PROTOCOL=tcp)(HOST=rac1)(PORT=1599))

(ADDRESS=(PROTOCOL=ipc)(KEY=extproc))))

SID_LIST_LIST=

(SID_LIST=

(SID_DESC=

(GLOBAL_DBNAME=TEST01)

(ORACLE_HOME=/u03/ora11g/product/11.2.0/dbhome_1)

(SID_NAME=TEST01)))

tnsnames.ora

EXTPROC01=

(DESCRIPTION=

(ADDRESS=(PROTOCOL=ipc)(key=extproc))

(CONNECT_DATA=(SERVICE_NAME=TEST01))

)

如果配置没有问题,可以使用tnsping来验证一下服务是否可用。

[ora11g@rac1 admin]$ tnsping extproc01

TNS Ping Utility for Linux: Version 11.2.0.3.0 - Production on 24-FEB-2015 06:03:53

Copyright (c) 1997, 2011, Oracle.  All rights reserved.

Used parameter files:

Used TNSNAMES adapter to resolve the alias

Attempting to contact (DESCRIPTION= (ADDRESS=(PROTOCOL=ipc)(key=extproc)) (CONNECT_DATA=(SERVICE_NAME=TEST01)))

OK (0 msec)接下来我们来实现一个简单的函数,大过年的我们就以红包为例。我们传入红包的金额,直接放大100倍。比如传入8块,直接输出800.

cat test.c

test(n)

int n;

{

int lucky_money;

lucky_money=100*n;

return (lucky_money);

}

对编写的c程序做编译,生成动态链接库文件,然后直接拷贝到$ORACLE_HOME/bin下

[ora11g@rac1 extproc]$ cc -shared -o test.so test.c

[ora11g@rac1 extproc]$ ll

total 12

-rw-r--r-- 1 ora11g dba   83 Feb 24 05:42 test.c

-rwxr-xr-x 1 ora11g dba 5609 Feb 24 05:42 test.so

[ora11g@rac1 extproc]$ cp test.so $ORACLE_HOME/bin

这个时候我们就开始创建库文件,指向test.so,然后把权限赋予指定的用户。

SQL> create  or replace library test_code as '$ORACLE_HOME/bin/test.so';

/

Library created.

SQL> grant execute on test_code to n1;

Grant succeeded.

有了库文件,我们就开始定义函数,这个函数最终给会调用链接库文件

create or replace function func_test

(x binary_integer)

return binary_integer

as language C

library sys.test_code

name "test";

/

到此为止就大功告成了,我们的函数就创建成功了,来简单验证一下。

set serveroutput on

var lucky_money number;

var amount number;

exec :lucky_money :=8888;

exec :amount := func_test(8888);

print amount;

SQL>

AMOUNT

----------

888800这种方式能够屏蔽代码层的抽象,直接开放丰富的功能,还是比较实用的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值