从事数据库工作多年,目前看好分布式NeSQL/HTAP数据库在企业客户市场的发展。未来的主要方向是——致力于 NewSQL/HTAP 数据库的推广普及。
分类: 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的方法参数和返回值的详细说明,参见如下官方网址:
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