Java 感知Mysql存储过程变量数量

在项目中,可能会遇到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();
	}

}

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

时间: 2024-11-05 14:59:57

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

Java调用MySQL存储过程

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

JAVA调用mysql存储过程noAccessToProcedureBodies错误

问题:在JAVA中调用MYSQL存储过程遇到以下报错: java.sql.SQLException: User does not have access to metadata required to determine stored procedure parameter types. If rights can not be granted, configure connection with "noAccessToProcedureBodies=true" to have dri

mysql存储过程变量的拼接

存储过程变量的拼接   有时候我们需要模糊查询,但是同时我们又要 在模糊查询的时候使用变量,我们又想在变量的后面拼接一个%去匹配模糊查询   那么就会用到 concat函数   示例如下:  www.2cto.com      SELECT count(id) FROM config WHERE name like  concat(studentName,'%');    其中studentName是变量,   如果复制studentName的值=‘李’   那么效果相当于  SELECT co

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

先说MySQL的字符集问题.Windows下可通过修改my.ini内的 [mysql] default-character-set=utf8    //客户端的默认字符集 在MySQL客户端工具中输入SHOW VARIABLES LIKE 'character%'; 显示如下 这样执行读取信息返回中文为乱码,解决办法是,在连接数据库之后,读取数据之前,先执行一项查询 SET NAMES 'utf8'; 即可显示正常. 最简单的完美修改方法,修改mysql的my.cnf文件中的字符集键值(注意配置

Mysql存储过程(Java)

这是我学习mysql存储过程时关心的几个点内容,希望能对你们学习存储过程有所帮助. 语法: create procedure sp_name ([proc_parameter[,...]]) [characteristic ...]begin.......end Proc_parameter:存储过程的参数列表,多个参数彼此间用逗号分隔      格式[IN|OUT|INOUT] param_name type IN(输入参数).OUT(输出参数).INOUT(输出参数和输入); Param_n

mysql -- 存储过程中 declare 和 set 定义变量的区别

mysql存储过程中,定义变量有两种方式:1.使用set或select直接赋值,变量名以 @ 开头.例如:set @var=1;可以在一个会话的任何地方声明,作用域是整个会话,称为会话变量. 2.以 DECLARE 关键字声明的变量,只能在存储过程中使用,称为存储过程变量,例如:DECLARE var1  INT DEFAULT 0;  主要用在存储过程中,或者是给存储传参数中. 两者的区别是:在调用存储过程时,以DECLARE声明的变量都会被初始化为 NULL.而会话变量(即@开头的变量)则不

MySQL存储过程及触发器

一.存储过程 存储过程的基本格式如下: -- 声明结束符 -- 创建存储过程 DELIMITER $ -- 声明存储过程的结束符 CREATE PROCEDURE pro_test() --存储过程名称(参数列表) BEGIN -- 可以写多个sql语句; -- sql语句+流程控制 SELECT * FROM employee; END $ -- 结束 结束符 -- 执行存储过程 CALL pro_test(); -- CALL 存储过程名称(参数); -- 删除存储过程 DROP PROCE

mysql存储过程、存储函数及流程控制

存储过程 一.基本语法 create procedure sp_name([proc_parameter[,...]]) [characteristic...]routine_body begin end sp_name 表示存储过程的名字 proc_parameter 存储过程参数例表[IN OUT INOUT]三个部分组成 其中IN 表示传进来的参数 其中OUT 表示传出去的参数 其中INOUT 表示传进来但最终传回的参数 routine_body 参数是SQL代码的内容(类似于触发器的fo

MySQL存储过程实例

一.创建MySQL数据库函数 TCC:无参数,查询fruit表中的所有数据 : TAA:两个参数,查询fruit总共有多少行:查询ids为某个值时水果表的数据 TDD:两个参数,查询ids不等于某个值,数量大于某个值,水果表的数据 二.Java操作MySQL函数 package com.itnba.maya.cunchu; import java.util.*; import java.sql.*; public class Test { public static void main(Stri