26 开发自定义计算函数

要增强可用于 Essbase 块存储多维数据集的计算函数,可以使用 Java 开发自己的自定义函数 (custom-defined function,CDF)。编写函数后,安装 Java 类,然后向 Essbase Server 全局注册函数,或向应用程序本地注册函数。

您可以在 Essbase 计算脚本中使用自定义函数。

Essbase 不提供用于创建 Java 类和归档文件的工具;您必须具有受支持的 JDK 版本。

有关自定义函数的示例,请参见Java Code Examples

定制定义的函数仅适用于块存储多维数据集(与聚合存储多维数据集无关)。

要创建自定义函数,请使用以下工作流。

  1. 查看自定义函数的要求:自定义函数的有效性要求

  2. 编写一个公共 Java 类,其中至少包含一个要用作自定义函数的公共静态方法:为自定义函数创建和编译 Java 类

  3. 安装 Java 类:在 Essbase 服务器上安装 Java 类

  4. 将自定义函数注册为本地或全局函数:注册自定义函数

自定义函数的有效性要求

您可以将 Essbase 自定义函数设计为 Java 类中的方法。对于全局函数,在一个类中编写方法。对于应用程序功能,每个应用程序使用单独的类和 jar 文件。在全局注册函数之前,在本地测试一个应用程序的函数。请注意支持的数据类型、变量和命名约定。

您可以在一个类中创建多个方法,以用作自定义函数。通常,Oracle 建议您创建计划在 Essbase Server 上的所有应用程序中使用作为单个类中自定义函数的方法。但是,如果您计划添加将在 Essbase Server 上的选择性应用程序中使用的自定义函数,请在单独的类中创建这些自定义函数,并将它们添加到单独的 .jar 文件中的 Essbase Server 中。

创建多个包含用作自定义函数的方法的 Java 类时,请验证每个类名称是否唯一。重复的类名会导致无法识别重复类中的方法,并且无法将这些方法注册为自定义函数。

在 Java 中使用测试程序,测试 Java 类和方法。如果对这些方法的输出感到满意,请将其安装在 Essbase Server 上,然后在单个测试应用程序中注册。请勿在全球范围内注册用于测试的功能;如果遇到问题,这样做会使更新功能变得更加困难。

自定义函数中的方法可以具有以下受支持数据类型的任意组合作为输入参数:

  • 布尔值

  • 字节

  • 字符

  • com.hyperion.essbase.calculator.CalcBoolean

  • float, double

  • java.lang.String

  • short、int、long

  • 任意这些类型的数组

CalcBoolean 是 Essbase 特定的数据类型,可以包含三个值:TRUE、FALSE 和 #MISSING。有关列出的其他数据类型的信息,请参见 JDK 文档。

方法返回的数据类型可以是 void 或上述任何数据类型。返回的数据类型将转换为特定于 Essbase 的数据类型。字符串将映射到字符串类型。布尔值映射到 CalcBoolean 数据类型。所有其他值都映射到 double 类型。

注意:

Essbase 不支持返回具有无限值或非数字值的双变量。如果这些值是从 Java 程序返回的,则可能无法在 Essbase 中正确记录或显示它们。在返回到 Essbase 之前,应检查双变量以查找无限值或非数字值,并将其设置为有限值。请参见 JDK 文档中 Double 类的条目。

对于创建、删除和管理自定义函数, Essbase 需要以下安全权限:

  • 本地、应用程序范围的自定义函数:应用程序管理器或更高版本

  • 全局、服务器范围的自定义函数:系统管理员

Essbase 中注册自定义函数时,会为该函数指定一个名称,该名称用于计算脚本和公式,并且与函数使用的 Java 类和方法名称不同。

对自定义函数进行命名时,请遵循以下要求:

  • 使用 @ 符号开始名称。函数名称的其余部分可以包含字母、数字和以下符号:@、#、$ 和 _。函数名称不能包含空格。

    例如:@MYFUNCTION

  • 启动仅由带有“@_”的自定义宏调用的自定义函数的名称,以将其与一般用途函数和宏区分开来。

    例如:@_MYFUNCTION

  • 自定义函数必须具有唯一的名称。函数名称必须彼此不同,从自定义宏的名称,到现有计算函数的名称。

  • 如果 Essbase 应用程序包含与全局函数同名的本地函数,则本地函数将用于计算。

为自定义函数创建和编译 Java 类

要为 Essbase 自定义函数 (custom defined function,CDF) 创建和编译 Java 类,请使用文本编辑器或 IDE(integrated development environment,集成的开发环境)编写该类,并使用 javac 工具对其进行编译。

下面是用于为 CDF 创建 Java 类的工作流示例:

  1. 在文本编辑器中,创建一个 Java 类。

    例如:

    public class CalcFunc {
      public static double sum (double[] data) {
        int i, n = data.length;
        double sum = 0.0d;
        for (i=0; i<n; i++) {
          double d = data [i];
          sum = sum + d;
        }
        return sum;
      }
    }
    
  2. 保存扩展名为 .java 的文件。

    例如:

    CalcFunc.java
  3. 导航到 .java 文件所在的目录;在命令提示符下,输入以下命令:
    javac java_filename

    例如:

    javac CalcFunc.java
  4. 解决任何编译错误,直到编译器创建扩展名为 .class 的新文件。

    例如:

    CalcFunc.class

Essbase 服务器上安装 Java 类

要将自定义计算函数 (CDF) 的 Java 类安装到 Essbase Server 上,请对其进行编译,将 jar 文件复制到这些说明中指定的全局或应用程序级别 udf 目录,然后重新启动应用程序或服务器。

Java 类必须使用 JDK jar 工具在 JAR 文件中编译。

要创建 .jar 文件并将其安装在 Essbase 服务器上,请执行以下操作:

  1. 导航到 .class 文件所在的目录;在命令提示符下,输入以下命令:
    jar cf jar_filename class_filename

    例如:

    jar cf CalcFunc.jar CalcFunc.class
  2. Essbase Server 上,将 .jar 文件复制到以下目录之一(如果该目录不存在,请创建该目录):
    • 对于包含全局定制定义函数的 .jar 文件:

      ESSBASEPATH/java/udf/
    • 对于仅与特定应用程序一起使用的 .jar 文件:

      <Application Directory>/app/appname/udf/

      其中,appname 是将使用本地 CDF 的应用程序的名称。

    如果您不知道 ESSBASEPATH<Application Directory> 的位置,请参阅 Essbase 平台中的环境变量

    如果随后将 .jar 文件放置在其他位置,则必须修改 CLASSPATH 变量以包括 .jar 文件的完整路径和文件名。

  3. 如果这些函数将仅由特定应用程序使用,请重新启动这些应用程序。否则,请重新启动 Essbase Server有关独立部署,请参见 Start、Stop 和 Check Servers ;有关 OCI 上的堆栈部署,请参见 Use Commands to Start、Stop and View Status of Processes

注册自定义函数

使用 MaxL 将自定义函数 (CDF) 注册到 Essbase 中。注册任务是在 Java 类中编写了 CDF,编译了类并安装了 jar 文件之后完成的。

将 CDF 的 Java 类编译为 .jar 文件并在 Essbase Server 上安装 .jar 文件后,必须先注册函数,然后才能在计算脚本和公式中使用这些函数。请参阅自定义函数的有效性要求

注册全局 CDF 时, Essbase 服务器上的所有 Essbase 应用程序都可以使用它。在将函数设为全局之前,在单个应用程序中测试函数(并仅在该应用程序中注册它们)。

使用与更新宏目录相同的过程来更新函数目录。请参见 Refresh the Catalog of Custom-Defined 宏

注意:

不要注册用于测试的全局函数;如果遇到问题,这样做会使更改它们变得更加困难。

要注册 CDF,请使用 create function MaxL 语句。

要将 CDF 注册到本地范围,请将应用程序名称作为前缀。例如,以下 MaxL 语句将 CalcFunc 类中的函数 @JSUM 注册为本地函数,以便在示例应用程序中使用:

create function Sample.'@JSUM'
as 'CalcFunc.sum'
spec '@JSUM(memberRange)'
comment 'adds list of input members';

要向全局范围注册 CDF,请不要将应用程序名称作为前缀。例如,以下 MaxL 语句将 CalcFunc 类中的函数 @JSUM 注册为全局函数,以便在 Essbase Server 上的任何应用程序中使用:

create function '@JSUM'
as 'CalcFunc.sum'
spec '@JSUM(memberRange)'
comment 'adds list of input members';

注意:

为 Java 方法指定输入参数是可选的。如果未指定输入参数,则 Essbase 将从 Java 代码中的方法定义中读取这些参数。但是,如果要使用相同的方法名称注册多个 CDF,但使用不同的参数集,则必须分别注册每个版本的函数,并为每个版本的函数指定参数。

实施已注册的自定义函数

可以在计算脚本和公式中使用已注册的自定义函数 (custom-defined function,CDF),就像使用本机 Essbase 计算函数一样。

要使用注册的 CDF,请执行以下操作:

  1. 创建或打开现有的计算脚本或公式。
    • 如果 CDF 在本地注册(在特定应用程序中),则必须在该应用程序中使用计算脚本或公式。

    • 如果 CDF 已全局注册,则可以在 Essbase Server 上使用任何计算脚本或公式。

  2. 将函数添加到计算脚本或公式。

    例如,要使用 JSUM,请使用此计算脚本:

    "New York" = @JSUM(@LIST(2.3, 4.5, 6.6, 1000.34));

    将此计算脚本与 Sample.Basic 示例数据库一起使用,或将 "New York" 替换为测试数据库中成员的名称。

  3. 保存计算脚本或公式,然后照常运行它

更新自定义功能

要更新 Essbase 自定义定义函数 (custom defined function,CDF),请确定它在作用域中是本地还是全局,关闭受影响的应用程序,替换包含函数代码的 .jar 文件,然后重新注册函数。

更新 CDF 的过程取决于以下条件:

  • 函数是本地注册还是全局注册。

  • CDF 的签名(类名称、方法名称或输入参数)在 Java 代码中已更改。

通常,要更新 CDF,必须替换包含函数代码的 .jar 文件,然后重新注册该文件。但是,如果 CDF 的签名没有更改,并且它只有一个输入参数集(它不是重载的方法),则可以替换包含该函数的 .jar 文件。

注意:

只有管理员才能更新全局 CDF。

要更新 CDF,请执行以下操作:

  1. 确定函数是本地函数还是全局函数。

    请参阅查看自定义函数

  2. 对 CDF 的 Java 类进行更改,并使用 Java 测试程序来测试其输出。
  3. 编译 Java 类并将其归档到新的 .jar 文件中,使用与上一个 .jar 文件相同的名称。

    包括以前 .jar 文件中包括的 CDF 的任何其他类和方法。

  4. 根据要更新本地或全局自定义函数,执行操作:
    1. 本地:关闭使用 .jar 文件中的函数的任何 Essbase 应用程序。
    2. 全局:关闭所有 Essbase 应用程序

    如果您不确定 Essbase 应用程序使用 .jar 文件中的哪些函数,请关闭所有 Essbase 应用程序。

  5. 将新 .jar 文件复制到 Essbase Server ,用相同的名称替换现有 .jar 文件。
  6. 如果 CDF 的签名未更改,请跳至步骤 8
  7. 要替换 CDF,请使用 create or replace function MaxL 语句。例如:
    • 本地:

      create or replace function sample.'@JSUM'
      as 'CalcFunc.sum';
    • 全局:

      create or replace function '@JSUM'
      as 'CalcFunc.sum';
  8. 重新启动您关闭的应用程序,这将更新目录。

查看自定义函数

Essbase 中查看自定义函数 (custom-defined function,CDF) 以确定它是否已成功注册,以及它在范围内是本地还是全局。CDF 在创建和注册后才会显示。

要查看 CDF,请执行以下操作:

使用 display function MaxL 语句。

例如,使用以下 MaxL 语句查看示例应用程序中的 CDF 以及所有已注册的全局函数:

display function Sample;

display function 语句列出没有应用程序名称的全局函数,以指示它们是全局的。如果应用程序包含与全局函数同名的函数,则仅列出本地函数。

删除自定义函数

要删除/注销 Essbase 自定义定义函数 (custom defined function,CDF),请首先确保它们未被使用。然后,关闭定义 CDF 的应用程序,通过发出 MaxL drop function 语句删除 CDF,然后重新启动受影响的应用程序。

删除 CDF 需要以下权限:

  • 本地:至少应用程序管理器的权限

  • 全局:系统管理员权限

在删除 CDF 之前,应验证没有计算脚本或公式在使用它们。全局 CDF 可用于 Essbase Server 中的计算脚本和公式,因此您必须先验证 Essbase Server 上的计算脚本或公式是否未使用全局 CDF,然后再将其删除。

注意:

仅当用户未访问 Essbase 多维数据集且未执行计算例程时,才删除全局 CDF。

要删除 CDF,请执行以下操作:

  1. 确定函数是本地函数还是全局函数。

    请参阅查看自定义函数

  2. 根据是删除本地还是全局 CDF,执行操作:
    1. 本地:关闭使用 .jar 文件中的函数的任何 Essbase 应用程序。
    2. 全局:关闭所有 Essbase 应用程序。
  3. 要删除 CDF,请使用 drop function MaxL 语句。例如:
    • 本地:

      drop function Sample.'@JSUM';
    • 全局:

      drop function '@JSUM';
  4. 重新启动您关闭的应用程序,这将更新目录。

复制自定义函数

您可以将自定义函数 (custom-defined function,CDF) 复制到您具有相应访问权限的任何 Essbase Server 和应用程序。

要复制 CDF,请使用 create or replace function as MaxL 语句。

自定义函数的性能注意事项

由于自定义函数是作为 Essbase 计算器框架的扩展实现的,因此您可能希望 CDF 的运行效率低于本机 Essbase 计算函数。

要优化性能,请将自定义函数的使用限制为无法使用本机 Essbase 计算命令函数执行的计算,尤其是在计算速度至关重要的应用程序中。