使用HSqlDB的过程中,因为业务需求要执行动态SQL时,才突然发现HSqlDB不具有类似于SQL Server等数据库的Exec的功能。于是一番探索之后就有了本文。
SQL-92提出了支持动态SQL的标准(12 Support for dynamic execution of SQL language)。各种主流的关系型数据库也提供了执行方法,比如SQL Server的Exec和sp_executesql。

SQL-99提出了SQL/JRT的概念,这其实也可执行动态SQL。简单来说,SQL/JRT就是提供了在SQL中访问Java的static method的能力,它也被称为Java Procedure。从维基说明来看,Oracle、DB2和HSqlDb都实现了SQL/JRT。HSqlDb的文档的第八章中也详细介绍了Java Language Routines (SQL/JRT),下面以HSqlDb为例,说明SQL/JRT的基本用法。

第一个例子:
SQL/JRT定义:

CREATE PROCEDURE get_customer(IN id INT, OUT firstname VARCHAR(50), OUT lastname VARCHAR(50)) READS SQL DATALANGUAGE JAVAEXTERNAL NAME 'CLASSPATH:org.hsqldb.test.Test01.getCustomerProcedure'

可以看到,存储过程中实际上需要调用Test01#getCustomerProcedure方法,该方法定义如下:

public static void getCustomerProcedure(int id, String[] firstn, String[] lastn)throws java.sql.SQLException {firstn[0] = somevalue;  // parameter out value is assignedlastn[0] = somevalue;   // parameter out value is assigned
}

存储过程调用代码:

CallableStatement c = conn.prepareCall("call get_customer(?,?,?)");
c.setInt(1,5);
c.execute();
String firstname = c.getString(2);
String lastname = c.getString(3);

大家不难看出,两者参数具有对应关系,但是比较特殊的是:OUT参数在Java method中被对应为数组,并且返回时必须放在数组的第一个元素。 第二个例子:
SQL/JRT定义:

CREATE PROCEDURE new_customer(firstname VARCHAR(50), lastname VARCHAR(50))MODIFIES SQL DATA LANGUAGE JAVADYNAMIC RESULT SETS 1EXTERNAL NAME 'CLASSPATH:org.hsqldb.test.Test01.newCustomerProcedure'

可以看到,此存储过程中实际上需要调用Test01#newCustomerProcedure方法,该方法定义如下:

public static void newCustomerProcedure(String firstn, String lastn,ResultSet[] result) throws java.sql.SQLException {result[0] = someresultset;  // dynamic result set is assigned
}

存储过程调用代码:

CallableStatement c = conn.prepareCall("call new_customer(?,?)");
c.setString(1,"firstName");
c.setString(2,"lastName");
c.execute();
if (c.getMoreResults())
{ResultSet rs = c.getResultSet();
}

相比上例,该例没有OUT参数,但是却有一个需要返回的记录集(DYNAMIC RESULT SETS 1),Java method处理方式与上例类似,将需要返回的结果赋给了参数数组的第一个元素。 SQL/JRT中调用的Java method必须注意以下事项:
1. 定义必须为static,而且返回值必须为void;
2. 存储过程与Java method必须参数对应。对于OUT参数,method中参数必须声明为数组,并且返回值必须作为数组第一个元素;
3. Java method如需进行JDBC操作,可使用外部Connection对象,也可使用SQL/JRT提供的jdbc:default:connection。
第三点大家可能不是很明白,还是看看下面的例子吧。
SQL/JRT定义:

CREATE PROCEDURE proc1(IN P1 INT, OUT P3 INT)SPECIFIC P2 LANGUAGE JAVA DETERMINISTIC MODIFIES SQL DATA EXTERNAL NAME 'CLASSPATH:org.hsqldb.test.TestStoredProcedure.procTest2'");

Java method定义:

public static void procTest2(int p1, Integer[] p3) throws java.sql.SQLException {Connection conn = DriverManager.getConnection("jdbc:default:connection");java.sql.Statement stmt = conn.createStatement();stmt.execute("INSERT INTO MYTABLE VALUES(" + p1 + ",'test1')");java.sql.ResultSet rs = stmt.executeQuery("select * from MYTABLE");java.sql.ResultSetMetaData meta = rs.getMetaData();int cols  = meta.getColumnCount();p3[0] = Integer.valueOf(cols);rs.close();stmt.close();}//orpublic static void procTest2(Connection conn, int p1, Integer[] p3) throws java.sql.SQLException

两种定义方式效果是等价的。第一种不要调用conn.close()去试图关闭SQL/JRT维护的Connection。第二种SQL/JRT会自动忽略Java method的第一个Connecton参数。
下面列出两种数据类型的对应关系:

SQL/JRT类型        Java类型
SMALLINT        short or Short
INT         int or Integer
BIGINT          long or Long
NUMERIC  or DECIMAL BigDecimal
FLOAT  or DOUBLE    double or Double
CHAR or VARCHAR     String
DATE            java.sql.Date
TIME            java.sql.Time
TIMESTAMP       java.sql.Timestamp
BINARY          Byte[]
BOOLEAN         boolean or Boolean
ARRAY of any type   java.sql.Array
TABLE           java.sql.ResultSet

看到这里,大家应该明白怎么在HSqlDB中执行动态SQL了吧......

使用HSqlDB的SQL/JRT功能相关推荐

  1. sql序列(2) sql语句功能表

    这里提供一份 sql语句功能表,大家可以根据关键字去梳理自己的知识点 https://files.cnblogs.com/files/namedL/sql%E8%AF%AD%E5%8F%A5%E5%8 ...

  2. oracle接收输入参数,Oracle带输入输出参数存储过程(包括sql分页功能)

    记录一下,免得以后忘记了又要到处去找. begin /*这里不能直接执行select语句但可以直接执行update.delete.insert语句*/ end里面不能接执行select语句,声明会话级 ...

  3. MySQL5.5.27使用Restore From SQL Dump功能导入数据库表中出现Row size too large

    问题描述:MySQL数据库版本为MySQL5.5.27,在使用其Restore From SQL Dump功能导入数据库表时出现以下错误提示 Row size too large. The maxim ...

  4. dms mysql定义变量_数据管理DMS:自建MySQL数据库 全量SQL诊断功能发布啦!-阿里云开发者社区...

    MySQL的用户都面临都一个难题,异常或者故障问题难定位,很多时候都靠"猜". 如果比较幸运,异常正在发生,我们还可以获取到会话.引擎状态等信息: 如果没有异常现场,要找到根因,除 ...

  5. 实时计算 Flink SQL 核心功能解密

    2019独角兽企业重金招聘Python工程师标准>>> 实时计算 Flink SQL 核心功能解密 Flink SQL 是于2017年7月开始面向集团开放流计算服务的.虽然是一个非常 ...

  6. 集成开发环境PL/SQL Developer v13.0新功能(二)——PL / SQL美化功能增强

    Allround Automations是一家位于荷兰的私人控股公司.该公司成立于1989年,在Oracle开发工具方面是全球领先的服务提供商.其中,产品PL/SQL Developer是一个集成开发 ...

  7. HHDEBC与其他主流软件SQL格式化功能的对比

    SQL格式化(即SQL美化)是一项非常重要的功能.只有清晰的结构,才能让您更好的优化数据库查询或写入. HHDBCS的SQL格式化功能有着独特的处理方式,可运用于对复杂SQL语句的分析或者是程序代码优 ...

  8. mysql5.5太平洋,太平洋软件下载站SQL全功能新云2.1商业版代码 下载

    太平洋软件下载站SQL全功能新云2.1商业版代码 下载 更新时间:2007年04月17日 00:00:00   作者: 运行环境:Asp/Access/Asp/Mssql/ 文件大小:30.76 MB ...

  9. 组件分享之后端组件——基于Golang实现的database/sql附加功能组件dbr

    组件分享之后端组件--基于Golang实现的database/sql附加功能组件dbr 背景 近期正在探索前端.后端.系统端各类常用组件与工具,对其一些常见的组件进行再次整理一下,形成标准化组件专题, ...

  10. 【SQL Performance】历史SQL监控(Historical SQL Monitoring ) 功能(12c)

    概述 历史SQL监控使用的例子 关于Automatic Report Capturing 相关视图和程序包 相关参数 参考 概述 Oracle 11g版本 推出了实时SQL监控功能(Real-Time ...

最新文章

  1. Winodws 10 如何安装wget
  2. 初学Java多线程【1】:线程简介
  3. Algs4-1.4.8计算输入文件中相等的整数对的数量
  4. 温斯顿英语 PHP,温斯顿英语
  5. 目标指令c语言是什么,什么是C中的目标文件?
  6. 关于控件的AutoSize属性影响界面布局的问题解决
  7. mysql 条件分析_数据分析之mysql
  8. linux加密框架 crypto 算法管理 - 动态和静态算法管理
  9. 用VB构键Internet的应用
  10. python0_python中0o1010是多少
  11. 机电传动控制 第一周作业
  12. RecyclerView Widget 使用
  13. Java CXF框架(案例加解析)(快速入门)模拟服务端和客户端(客户端远程调用服务端功能)
  14. Leetcode-845. 数组中的最长山脉(最详细解法)
  15. 第11章从 Web 抓取信息
  16. 生日祝福电子贺卡html5,电子生日祝福卡
  17. java tic tac toe_Tic Tac Toe java
  18. redis短信发送限制
  19. Linux 命令(204)—— ss 命令
  20. 2020-03-10

热门文章

  1. Java8 新特性之stream
  2. 解除控制伽卡他卡控制
  3. outlook附件无图标_通过将图标列添加到Outlook 2007待办事项栏中,一目了然地查看任务类型...
  4. 《简约至上:交互式设计四策略》读书感悟
  5. Hadoop安装snappy(编译源码)
  6. 解决安装虚拟机vmware无法打开注册表项的问题
  7. NVIDIA Jetson TK1学习与开发——手动刷机
  8. Python 编程之Tkinter的使用01
  9. 关于Node.js中内存管理的思考与实践
  10. 亿格瑞A5-hdmi故障了