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();
} }
该代码对存储过程的感知,是利用正则表达式的,所以在匹配的时候,可能遇到一些极端的情况,如 注释中包含了符合规则的 语句,不过一般来说,这种情况极少发生。
Java 感知Mysql存储过程变量数量的更多相关文章
- Java调用MySQL存储过程
Java调用MySQL的存储过程,需要用JDBC连接,环境eclipse 首先查看MySQL中的数据库的存储过程,接着编写代码调用 mysql> show procedure status; + ...
- mysql存储过程变量的拼接
存储过程变量的拼接 有时候我们需要模糊查询,但是同时我们又要 在模糊查询的时候使用变量,我们又想在变量的后面拼接一个%去匹配模糊查询 那么就会用到 concat函数 示例如下: www. ...
- mysql 存储过程变量的定义
Mysql变量: 1.DECLARE variable_name datatype(size) DEFAULT default_value; 此处声明的相当于一个局部变量 ,在end 之后便失效. 声 ...
- JAVA 调用mysql存储过程
public class Test { //连接mysql数据库 public static final String DRIVER_CLASS = "com.mysql.jdbc.Driv ...
- 解决Java连接MySQL存储过程返回参数值为乱码问题
先说MySQL的字符集问题.Windows下可通过修改my.ini内的 [mysql] default-character-set=utf8 //客户端的默认字符集 在MySQL客户端工具中输入 ...
- mysql 存储过程变量及循环的使用
1.用游标循环 BEGIN -- 定义变量 -- 定义done DECLARE done INT; -- 定义 ammeter_id_bl DECLARE ammeter_id_bl DOUBLE; ...
- Mysql存储过程给变量赋值的几种方法实践
BEGIN DECLARE v_request_count INT; #申请次数 DECLARE v_plan_count INT; #安排次数 DECLARE v_learn_count INT; ...
- Mysql存储过程查询结果赋值到变量的方法
Mysql存储过程查询结果赋值到变量的方法 把查询结果赋值到变量,大部分情况下使用游标来完成,但是如果明确知道查询结果只有一行(例如统计记录的数量,某个字段求和等),其实可以使用set或into的 ...
- MySQL 存储过程的变量
MySQL 存储过程的变量 变量是一个命名数据对象,变量的值可以在存储过程执行期间更改.我们通常使用存储过程中的变量来保存直接/间接结果. 这些变量是存储过程的本地变量. 注意:变量必须先声明后,才 ...
随机推荐
- 具体分析Struts工作流程
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXV3ZW56aGU=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA ...
- IntelliJ Idea中一个编译报错引发的
package verify; public class Verifier { private String name; public Verifier() { this.name = getClas ...
- 五个项目管理学习笔记.沟通技巧II
两.通信模型:沟通的双向过程 沟通模型: 编 码---------------->信息-----------------> 解码&歧义 发送者 ...
- Request processing failed; nested exception is org.springframework.dao.InvalidDataAccessApiUsageException: Multiple representations of the same entity解决方法
1.错误信息 Request processing failed; nested exception is org.springframework.dao.InvalidDataAccessApiUs ...
- 【从翻译mos文章】oracle linux 和外部存储系统 关系
oracle linux 和外部存储系统 关系 参考原始: Oracle Linux and External Storage Systems (Doc ID 753050.1) 范围: Linux ...
- C#关于HttpClient的应用(二):融云IM集成
public class RcHttpClient:BaseHttpClient { private String appKey; private String appSecret; public R ...
- Android测试流量的几种方法
1. tcpdump + wireshark 1.1 tcpdump抓包 注意:Android设备使用tcpdump需要root权限 tcpdump是一个在Unix-like系统中通用的网络抓包工具, ...
- 【百度地图API】如何实现信息窗口轮询
原文:[百度地图API]如何实现信息窗口轮询 摘要: 很多微博或者SNS开发者,想结合地图展示用户的微博或者状态.这时,利用信息窗口就是最好的展示方式了. 在这里,我们使用信息窗口轮询的方式来实现这一 ...
- javascript中类的属性研究
原文:javascript中类的属性研究 本篇文章主要针对javascript的属性进行分析,由于javascript是一种基于对象的语言,本身没有类的概念,所以对于javascript的类的定义有很 ...
- NetMQ
NetMQ发布订阅C#示例 NetMQ (ZeroMQ to .Net),ØMQ号称史上最快中间件.它对socket通信进行了封装,使得我们不需要写socket函数调用就能完成复杂的网络通信.和一般意 ...