注册
外部函数使用示例
专栏/培训园地/ 文章详情 /

外部函数使用示例

归途 2023/09/28 1236 0 0
摘要

说明

DM 提供了外部函数来调用 JAVA 编写的程序 Jar 包,通过在外部函数体中定义 Jar 包的相关信息,可以间接调用 Jar 包代码中的方法。

使用条件

使用正式授权

目前只有企业版和安全版支持外部函数功能,因此数据库必须使用正式授权才能启用。

打开 ENABLE_EXTERNAL_CALL 参数

ENABLE_EXTERNAL_CALL 静态参数,是否允许创建或执行外部函数: • 0 不允许(默认值) • 1 允许

此参数为静态参数,且不在 dm.ini 文件中,打开时不可直接在 dm.ini 文件中手动添加并重启。需要使用 SP 命令打开,之后重启数据库生效。

开启参数:

SP_SET_PARA_VALUE(2,'ENABLE_EXTERNAL_CALL',1);

如果没有正式授权,或未开启参数,则报错:

-5518: 第4 行附近出现错误:
没有创建函数权限

开启 dmAgent 服务

外部函数的执行通过 dmAgent 工具进行,执行前需要先启动此服务。在新版本数据库中,启动服务需要指定一个 agent.ini 配置文件,此文件中有两个关于外部函数的参数需要注意:

#ap
    ap_enable                                         = true                                              #whether enable ap plugin
    ap_port                                           = 6363                                              #ap listen tcp/ip port
  • ap_enable:是否启用外部函数功能,默认为 true
  • ap_port:外部函数端口,和 dm.ini 文件中的 EXTERNAL_JFUN_PORT 保持一致(默认是一致的)。

EXTERNAL_JFUN_PORT
动态,系统级参数,数据库执行 JAVA 外部程序时连接 dmagent 使用的端口。

  • 6363 默认值

未启动 dmAgent 服务时报错:

执行失败(语句1)
-7165: 外部函数连接DMAgent失败

编写外部函数

编写并生成 Jar 包

创建 JAVA 项目,在 src 下创建包 com.zhao.dm.outsidefun ,创建类 OutSideFun,类中创建一个计算两数相乘的方法,代码如下

package com.zhao.dm.oursidefun; /** * @packageName:com.zhao.dm.oursidefun * @className:OutSideFun * @Description: * @author:zhao * @date: */public class OutSideFun { public static int mult(int var1, int var2){ return var1 * var2; } }

注意:

  • 如果类中存在 main 方法,jar 打包时一定要选主方法。
  • JAR 包的权限不一定要是 dmdba
  • 建议方法定义为 static (非static也可以运行)
  • 外部函数存在缓存,运行过一次后,删除 JAR 包,重启数据库还可以正常运行,暂不清楚缓存周期。

创建外部函数

创建外部函数 J_MULT

CREATE OR REPLACE FUNCTION SYSDBA.J_MULT(a int, b int) RETURN int EXTERNAL '/opt/dmsetup/outSideFun/test06/DM_FUN.jar' "com.zhao.dm.oursidefun.OutSideFun.mult" USING java;

注意

  • 函数的参数个数,类型,返回值类型要和 JAVA 代码的方法中一致
  • 参数可以设置为 IN,OUT,IN OUT 类型,默认为 IN
  • 目前支持的参数类型为 INT,CHAR,VARCHAR,VARCHAR2 ,BIGINT,DOUBLE 分别对应 JAVA 中的 INT,STRING,LANG,DOUBLE 类型
  • EXTERNAL 后跟 JAR 包全路径和 JAR 包中项目包路径+类名+方法名

调用外部函数

调用上面创建的外部函数 J_MULT

SQL> SELECT J_MULT(2,3); 行号 J_MULT(2,3) ---------- ----------- 1 6

如果调用报错:
执行失败(语句1)

-104: INI参数文件错误

检查 JAR 包中类的路径是否正确,打包时是否选择了 main 方法。

使用外部函数解析XML数据

使用 dom4j 解析 xml 文件或字符串

编写代码

/** * @Author zhao * @Description * @Date * @Param [xmlStr] * @return **/ public static Document getDocument(String xmlStr) throws DocumentException { Document doc = null; return (Document) DocumentHelper.parseText(xmlStr); } /** * @Author zhao * @Description 获取根节点名称 * @Date * @Param [xmlStr] * @return **/ public static String getRootElement(String xmlStr) throws DocumentException { Element rootElement = getDocument(xmlStr).getRootElement(); return rootElement.getName(); }

创建外部函数

CREATE OR REPLACE FUNCTION SYSDBA.XMLDOM_GETALLATTR(a varchar) RETURN varchar EXTERNAL '/opt/dmsetup/outSideFun/test10/DM_XMLDOM.jar' "com.zhao.dm.xmldom.utils.XmlPar.getRootElement" USING java;

调用

SELECT SYSDBA.XMLDOM_GETALLATTR('<?xml version="1.0" encoding="UTF-8"?> <contactList id="0"> <contact id="001" class="style" name="lisi"> <name>张三</name> </contact> <contact id="002"> <name>李四</name> </contact> <contactTwo> <name>王五</name> </contactTwo> </contactList>') AS ATTR; 行号 ATTR ---------- ----------- 1 contactList 已用时间: 3.905(毫秒). 执行号:1104.
评论
后发表回复

作者

文章

阅读量

获赞

扫一扫
联系客服