在项目中,可能会遇到sybase 移植到 mysql的情况,因为sybase 支持存储过程的可变参数,而mysql不能支持,所以,在调用mysql的时候,需要感知存储过程到底有几个参数,来合理的配置参数数量:

如下是代码

package com.xxx.util;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Hashtable;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class ProcedureHelper { /*是否是开发模式*/
static boolean DEV = false;
static Map<String,Integer> CACHE = new Hashtable<String,Integer>(100);
static Pattern PATTERN_ARGS = Pattern.compile("`\\s*\\((.*)\\)\\s*begin",Pattern.DOTALL|Pattern.CASE_INSENSITIVE);
static Pattern PATTERN_ARG = Pattern.compile("(in|out|inout)[^-,]*(,|$)",Pattern.DOTALL|Pattern.CASE_INSENSITIVE);
private static int doWork(Connection con,String proc) throws Exception {
Statement stmt = null;
stmt = con.createStatement(); //3、Statement 接口需要通过Connection 接口进行实例化操作
ResultSet rs = stmt.executeQuery("show create procedure "+proc); if(rs.next()){
//第三列为 存储过程的代码
String code = rs.getString(3);
Matcher m = PATTERN_ARGS.matcher(code);
if(m.find()){
String args = m.group(1);
if(args.matches("\\s*"))
return 0;
else{
Matcher m2 = PATTERN_ARG.matcher(args);
int num = 0;
while(m2.find()){
//System.out.println(m2.group());
num++;
}
return num;
}
}else{
throw new RuntimeException("存储过程: "+proc+"无法通过正则表达式获取参数个数:\n"+code); }
}
rs.close();
stmt.close();
throw new RuntimeException("没有该存储过程"); }
/**
* 注意, 在存储过程的参数中,不能写注释,特别是 in xxx, 格式的注释,不然会被错误的识别
* @param con JDBC连接, 且不在函数内释放资源
* @param proc 调用的存储过程
* @param args 传递给存储过程的参数
* @throws 解析失败
* */
public static int getProcedureArgsNumber(Connection con,String proc) throws Exception {
if(con == null || proc == null|| proc.equals("")){
throw new RuntimeException("proc, con 参数不能为空");
}
//这里可以做缓存
return doWork(con,proc);
}
public static void main(String arg[]) throws Exception{ Connection con = null; //表示数据库的连接对象
Class.forName("com.mysql.jdbc.Driver"); //1、使用CLASS 类加载驱动程序
con = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=UTF-8","root","root"); //2、连接数据库
System.out.println(getProcedureArgsNumber(con,"my_procedure"));
con.close();
} }

  该代码对存储过程的感知,是利用正则表达式的,所以在匹配的时候,可能遇到一些极端的情况,如 注释中包含了符合规则的 语句,不过一般来说,这种情况极少发生。

Java 感知Mysql存储过程变量数量的更多相关文章

  1. Java调用MySQL存储过程

    Java调用MySQL的存储过程,需要用JDBC连接,环境eclipse 首先查看MySQL中的数据库的存储过程,接着编写代码调用 mysql> show procedure status; + ...

  2. mysql存储过程变量的拼接

    存储过程变量的拼接   有时候我们需要模糊查询,但是同时我们又要 在模糊查询的时候使用变量,我们又想在变量的后面拼接一个%去匹配模糊查询   那么就会用到 concat函数   示例如下:  www. ...

  3. mysql 存储过程变量的定义

    Mysql变量: 1.DECLARE variable_name datatype(size) DEFAULT default_value; 此处声明的相当于一个局部变量 ,在end 之后便失效. 声 ...

  4. JAVA 调用mysql存储过程

    public class Test { //连接mysql数据库 public static final String DRIVER_CLASS = "com.mysql.jdbc.Driv ...

  5. 解决Java连接MySQL存储过程返回参数值为乱码问题

    先说MySQL的字符集问题.Windows下可通过修改my.ini内的 [mysql] default-character-set=utf8    //客户端的默认字符集 在MySQL客户端工具中输入 ...

  6. mysql 存储过程变量及循环的使用

    1.用游标循环 BEGIN -- 定义变量 -- 定义done DECLARE done INT; -- 定义 ammeter_id_bl DECLARE ammeter_id_bl DOUBLE; ...

  7. Mysql存储过程给变量赋值的几种方法实践

    BEGIN DECLARE v_request_count INT; #申请次数 DECLARE v_plan_count INT; #安排次数 DECLARE v_learn_count INT; ...

  8. Mysql存储过程查询结果赋值到变量的方法

    Mysql存储过程查询结果赋值到变量的方法   把查询结果赋值到变量,大部分情况下使用游标来完成,但是如果明确知道查询结果只有一行(例如统计记录的数量,某个字段求和等),其实可以使用set或into的 ...

  9. MySQL 存储过程的变量

    MySQL  存储过程的变量 变量是一个命名数据对象,变量的值可以在存储过程执行期间更改.我们通常使用存储过程中的变量来保存直接/间接结果. 这些变量是存储过程的本地变量. 注意:变量必须先声明后,才 ...

随机推荐

  1. 试图加载格式不正确的程序。 (Exception from HRESULT: 0x8007000B)

    原文:试图加载格式不正确的程序. (Exception from HRESULT: 0x8007000B) 今天在电脑上部署公司的项目,出现这个错误.Bing后,找到原来是因为项目是32位的,而我的系 ...

  2. ReactJS入门二

    ReactJS入门学习二 ReactJS入门学习二 阅读目录 React的背景和基本原理 理解React.render() 什么是JSX? 为什么要使用JSX? JSX的语法 如何在JSX中如何使用事 ...

  3. Angular绑定数据时转义html标签

    AngularJs在绑定数据时默认会以文本的形式出现在页面上,比如我现在有这样一段代码 <div ng-controller="testCtrl">{{data}}&l ...

  4. interview(转)

    http://ifeve.com/ali-think-12/ http://ifeve.com/think-in-ali-10/

  5. 【SICP练习】150 练习4.6

    练习4-6 原版的 Exercise 4.6. Let expressions are derived expressions, because (let (( ) - ( )) ) is equiv ...

  6. Linux查看非root流程执行

    Linux查看非root流程执行 youhaidong@youhaidong-ThinkPad-Edge-E545:~$ ps -U root -u root -N PID TTY TIME CMD ...

  7. Log4j2 简明教程

    一.概述 log4j2官方文档内容非常多,要一次性了解全部是不可能的.正确的步骤应当是先了解最常见的配置,当发现原有知识无法解决问题,再重新查看文档看有没有合适的配置.下面将从文件结构入手,再到简单的 ...

  8. CSharp设计模式读书笔记(18):中介者模式(学习难度:★★★☆☆,使用频率:★★☆☆☆)

    中介者模式(Mediator Pattern):用一个中介对象(中介者)来封装一系列的对象交互,中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互,中介者模式又称为 ...

  9. easyui 小知识

    默认为今天 $(document).ready(function () {        $(function () {            var curr_time = new Date();  ...

  10. sql语句查询列的说明

    SELECT C.name,value FROM sys.columns C INNER JOIN sys.tables T ON C.object_id = T.object_idINNER JOI ...