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

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

在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

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

目录
相关文章
|
1月前
|
SQL 关系型数据库 MySQL
【MySQL 数据库】2、MySQL 的数据控制语言、函数和约束
【MySQL 数据库】2、MySQL 的数据控制语言、函数和约束
31 0
|
5月前
|
XML 开发框架 前端开发
J2EE之自定义框架知识(下篇 综合运用增删改查)
J2EE之自定义框架知识(下篇 综合运用增删改查)
40 0
|
3月前
|
存储 Java 数据库
JAVAEE框架数据库技术之13_oracle 之PLSQL技术及存储过程和函数(二)
JAVAEE框架数据库技术之13_oracle 之PLSQL技术及存储过程和函数
38 0
|
3月前
|
SQL Oracle 关系型数据库
JAVAEE框架数据库技术之12_oracle常用函数和高级查询子查询
JAVAEE框架数据库技术之12_oracle常用函数和高级查询子查询
67 0
JAVAEE框架数据库技术之12_oracle常用函数和高级查询子查询
|
17天前
|
存储 关系型数据库 MySQL
【mybatis-plus】Springboot+AOP+自定义注解实现多数据源操作(数据源信息存在数据库)
【mybatis-plus】Springboot+AOP+自定义注解实现多数据源操作(数据源信息存在数据库)
|
1月前
|
SQL 存储 关系型数据库
数据库迁移mssql to pgsql之函数转换
数据库迁移mssql to pgsql之函数转换
|
2月前
|
Oracle 关系型数据库 MySQL
|
2月前
|
存储 数据库
【数据库】分支与循环&函数&存储过程
【数据库】分支与循环&函数&存储过程
22 1
|
2月前
|
存储 数据库 C语言
期末速成数据库极简版【分支循环&函数】(4)
期末速成数据库极简版【分支循环&函数】(4)
32 1
|
2月前
|
人工智能 运维 关系型数据库
数据库基础入门 — 函数
数据库基础入门 — 函数
19 0

热门文章

最新文章