Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1462679
  • 博文数量: 201
  • 博客积分: 2812
  • 博客等级: 少校
  • 技术积分: 3029
  • 用 户 组: 普通用户
  • 注册时间: 2011-01-18 18:28
个人简介

从事数据库工作多年,目前看好分布式NeSQL/HTAP数据库在企业客户市场的发展。未来的主要方向是——致力于 NewSQL/HTAP 数据库的推广普及。

文章存档

2016年(1)

2015年(8)

2014年(23)

2013年(50)

2012年(32)

2011年(87)

分类: Sybase

2015-07-20 12:01:25

在先前的博文中介绍了IQ中使用java语言编写标量udf的例子。本文将向大家介绍“表udf”的编写示例。表udf能够返回多条记录(结果集)或多个值。下面结合一个示例加以介绍。

1. 环境说明

   * SAP IQ 16.0 SP08.30

   * 虚拟机一台,操作系统Linux 64bit

   * 使用IQ demo数据库

   * JDK 1.7.0_75

2. 编写RowGenerator标量udf函数。

  Java包名修改为udf.example,原先标量udf示例的java包为example。修改包名后,更加直观易读。


 --下面是示例源代码

package udf.example;

import java.sql.*;

public class RowGenerator {

  

public static void rowGenerator( int numRows, ResultSet rset[] ) 

{

    // 为结果集创建元数据:比如表名、列名和类型等

    ResultSetMetaDataImpl rsmd = new ResultSetMetaDataImpl(2);

    // 设置结果集第1列的元数据,数据类型为SQL类型 INTEGER.

    rsmd.setColumnType(1, Types.INTEGER);

    rsmd.setColumnName(1,"c1");

    rsmd.setColumnLabel(1,"c1");

    rsmd.setTableName(1,"MyTable");

    // 设置结果集第2列的元数据,数据类型为VARCHAR 255

    rsmd.setColumnType(2, Types.VARCHAR);

    rsmd.setColumnName(2,"c2");

    rsmd.setColumnLabel(2,"c2");

    rsmd.setColumnDisplaySize(2, 255);

    rsmd.setTableName(2,"MyTable");

        

    // 创建结果集

    ResultSetImpl rs = null;

    try {

      rs = new ResultSetImpl( (ResultSetMetaData)rsmd );

      rs.beforeFirst();  // 移动到结果集的最开始

    } catch( Exception e ) {

      System.out.println( "Error: couldn't create result set." );

      System.out.println( e.toString() );

    }

    

    // 下面的代码生成结果集包含的记录,记录数由参数numRows指定

    for( int i = 0; i < numRows; i++ ) {

      try {

        rs.insertRow();   // 插入一个空行

        rs.updateInt( 1, i );  //为该行的第1列赋值

        rs.updateString( 2, ("Str" + i) );  // 为第2列赋值

      } catch( Exception e ) {

        System.out.println( "Error: couldn't insert row/data on row " + i );

        System.out.println( e.toString() );

      }        

    }

    try {

        rs.beforeFirst();  // 把结果集的行指针移动到开始。

    } catch( Exception e ) {

        System.out.println( e.toString() );

    }

    rset[0] = rs;  // 把结果集赋予返回参数

  }

}

说明:ResultSetMetaDataImpl 和 ResultSetImpl 这两个类的代码也在udf.example包中,由于代码比较长,不在这里列出,大家可以参见3中的说明,从百度上下载。

3. 编译

  为了方便大家学习、动手实验。我把本人环境中的$IQDIR16/udf/java中的代码和相关编译打包脚本放到了百度盘上,大家可以下载使用。下载地址如下:

     

  为了编译这个例子,执行如下步骤:

  (1) cd $IQDIR16/

  (2) 把下载的udf.tgz拷贝到这个目录下

  (3) tar xvfz udf.tgz

     执行完上面的步骤后,会形成$IQDIR16/udf/java目录,里面包含了全部代码。

 
    (4) cd $IQDIR16/udf/java/src
    
(5) ./build.sh

 

     执行build.sh脚本,编译代码,并在$IQDIR16/udf/java/lib生成jar包。

 

4. 安装jar包到IQ数据库

   --启动dbisql工具

   dbisql -c "uid=DBA;pwd=sql" -nogui

   --执行如下命令(在我的环境中$IQDIR16目录是/opt/sybiq/16.0/IQ-16_0)安装包含java udf函数的jar包(包含示例类和相关类文件)

   INSTALL JAVA  NEW JAR 'myudf' FROM FILE '/opt/sybiq/16.0/IQ-16_0/udf/java/lib/myudf.jar'

5. 创建用户自定义函数

 CREATE or REPLACE PROCEDURE rowGenerator(IN numRows INTEGER) 

 RESULT (c1 INTEGER , c2 VARCHAR(255)) 

 EXTERNAL NAME 

 'udf.example.RowGenerator.rowGenerator(I[Ljava/sql/ResultSet;)V' 

 LANGUAGE JAVA

   说明:EXTERNAL_NAME是按照java包名.java类名.方法名指定的,括号中是方法的参数,右括号后面跟的是方法的返回类型.

 有关IQ udf的方法参数和返回值的详细说明,参见如下官方网址:

http://infocenter.sybase.com/help/index.jsp?topic=/com.sybase.infocenter.dc01034.1600/doc/html/jcu1303326630386.html

  

6. 在SQL语句中使用udf函数

   --执行如下语句,生成10条记录

   select * from rowGenerator(10);

7. 其他java udf函数管理命令

   (1) 更新已经安装好的java jar

   如果java用户自定义函数进行了修改,那么需要对已经安装到IQ数据库中的类进行更新。例如:

       INSTALL JAVA UPDATE JAR 'myudf' FROM FILE '/opt/sybiq/16.0/IQ-16_0/udf/java/lib/myudf.jar'

   (2) 删除安装的java jar

   例如:执行如下命令可以删除安装好的示例java jar包

       REMOVE JAVA JAR  'myudf' 

       DROP FUNCTION rowGenerator

阅读(3040) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~