原创性声明
此博文的出处 为 http://blog.csdn.net/zhujunxxxxx/article/details/39251241如果进行转载请注明出处。本文作者原创,邮箱zhujunxxxxx@163.com,如有问题请联系作者
一个java模拟的存储过程
在前两篇博客中介绍了存储过程的设计方法和数据结构。但是没有一个例子恐怕文章在好也没有很容易理解把
为此博主专门给了一个实例,我用java模拟了一个存储过程来实现,由于java下我没有进行词法语法解析,所以我的语法树就得自己来构造了(这真累)
我的所有表达式计算都是通过数据引擎计算的(其实很多数据库的存储过程都是这样的 比如postgresql)
先把给出我的数据结构
数据结构类
package java_test;
import java.util.List;
enum NodeType
{
t_none,t_var,t_stmt,t_create,t_declare,t_set,t_expr,
t_if,t_elseif,t_when,t_case,t_while,t_for,
t_exec,t_proc
}
enum DataType{
TT_INT,TT_CHAR,TT_BOOL,TT_DATE,TT_TIME,TT_APPROXNUM,TT_NULL,TT_VAR,TT_EXPR,TT_SIGN
}
class Node {
int dno;
NodeType node_type;
}
class VarNode extends Node{
String var_name;
DataType data_type;
int isconst;
int notnull;
String default_val;/*默认值*/
int isnull;
String setvalue;/*赋值过后值*/
ExprNode expr_value;
}
class DeclareNode extends Node{
List<Node> var_list;/*这个declare语句所包含的变量*/
}
class DeclNode extends Node{ /*定义存储过程的节点*/
String proc_name;/*存储过程名*/
List<Node> params;/*存储过程参数*/
}
/*终结点*/
class ProcNode extends Node{
DeclNode declnode;/*定义存储过程的节点*/
List<Node> proc_body;/*存储过程的具体块,我觉得它有各种 if-else declare set sql when-case for while 构成的list*/
List<Node> except_list;/*异常列表*/
}
class StmtNode extends Node{/*具体的一个sql语句节点*/
int sql_type;
String str_sql;
List<Node> params;/*此sql语句的参数*/
}
class SetNode extends Node{
List<Node> var_list;/*这个set语句所包含的变量,和具体的值*/
}
class ExprNode extends Node{
int is_const;/*是否是常量 -1 0 1*/
int is_wrap;/*是否有括号*/
DataType data_type;/*类型*/
String const_value;/*常量表达式的*/
String sign;
String param;
String str_value;/*无用*/
VarNode var_value;/*变量表达式的变量*/
ExprNode lnext;
ExprNode rnext;
}
class IfNode extends Node{
ExprNode expr;
List<Node> then_body;
List<Node> elseif_body;
List<Node> else_body;
}
class ElseIfNode extends Node{
ExprNode expr;
List<Node> body;
}
class CaseNode extends Node{
ExprNode expr;
List<Node> case_list;
int have_else;
List<Node> else_stmts;
}
class WhenNode extends Node{
ExprNode expr;
List<Node> stmts;
}
class WhileNode extends Node{
ExprNode expr;
List<Node> body;
}
class ForNode extends Node{
ExprNode lower;
ExprNode upper;
ExprNode step;
List<Node> body;
}
class ProcExecState{
int dno;
ProcNode proc;
int rettype;
Node lastnode;
Node nextnode;
String error;
}
class Dataum
{
DataType type;
String value;
boolean is_init;
public Dataum(DataType t)
{
this.type=t;
is_init=false;
}
public Dataum(DataType t,String v)
{
this.type=t;
this.value=v;
is_init=true;
}
}
这个类就是我们基本的数据结构
然后是一个解释器类,专门用来解释执行语法树的
解释器类
package java_test;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
enum ProcSQLState
{
PROC_SQL_RC_ERROR(0),
PROC_SQL_RC_OK(1),
PROC_SQL_RC_EXIT(2),
PROC_SQL_RC_CONTINUE(3),
PROC_SQL_RC_RETURN(4);
private int nCode ;
private ProcSQLState( int _nCode) {
this . nCode = _nCode;
}
public int toInt()
{
return this.nCode;
}
@Override
public String toString() {
return String.valueOf (this.nCode );
}
}
public class language {
public static MysqlHelper mysql=new MysqlHelper();
public static HashMap<String,Object> var_table =new HashMap<String,Object>();
public static int exec_stmts(ProcExecuteState estate,List<Node> stmts)
{
if(stmts==null)
return 0;
for (Node node : stmts) {
int rc=exec_stmt(estate,node);
if(rc==0)
return 0;
}
return 1;
}
public static int exec_stmt(ProcExecuteState estate,Node stmt)
{
int rc=-1;
switch(stmt.node_type)
{
case t_if:
rc=exec_stmt_if(estate,(IfNode)stmt);
break;
case t_while:
rc=exec_stmt_while(estate,(WhileNode)stmt);
break;
case t_case:
rc=exec_stmt_case(estate,(CaseNode)stmt);
break;
case t_declare:
rc=exec_stmt_declare(estate,(DeclareNode)stmt);
break;
case t_set:
rc=exec_stmt_assign(estate,(SetNode)stmt);
break;
case t_stmt:
rc=exec_stmt_sql(estate,(StmtNode)stmt);
break;
default:
break;
}
return rc;
}
public static int exec_stmt_declare(ProcExecuteState estate,DeclareNode stmt)
{
for (Node node : stmt.var_list) {
VarNode vnode=(VarNode)node;
if(vnode.isconst!=1)
{
Dataum data=new Dataum(vnode.data_type);
add_var(vnode.var_name,data);
}
}
return 1;
}
public static int exec_stmt_assign(ProcExecuteState estate,SetNode stmt)
{
for (Node node : stmt.var_list) {
VarNode vnode=(VarNode)node;
if(vnode.isconst!=1)
{
set_value(vnode.var_name,vnode.expr_value);
}
}
return 1;
}
public static int exec_stmt_if(ProcExecuteState estate,IfNode ifnode)
{
boolean value;
value=exec_eval_bool(estate,ifnode.expr);
if(value)
return exec_stmts(estate,ifnode.then_body);
for (Node item : ifnode.elseif_body) {
ElseIfNode eifnode=(ElseIfNode)item;
value=exec_eval_bool(estate,eifnode.expr);
if(value)
return exec_stmts(estate,eifnode.body);
}
return exec_stmts(estate, ifnode.else_body);
}
public static int exec_stmt_while(ProcExecuteState estate,WhileNode whilenode)
{
for(;;)
{
int rc;
boolean value;
value = exec_eval_bool(estate, whilenode.expr);
if(!value)
break;
rc = exec_stmts(estate, whilenode.body);
ProcSQLState erc=null;
switch(rc)
{
case 0: erc=ProcSQLState.PROC_SQL_RC_ERROR;
break;
case 1: erc=ProcSQLState.PROC_SQL_RC_OK;
break;
case 2: erc=ProcSQLState.PROC_SQL_RC_EXIT;
break;
case 3: erc=ProcSQLState.PROC_SQL_RC_CONTINUE;
break;
case 4: erc=ProcSQLState.PROC_SQL_RC_RETURN;
break;
default:
break;
}
switch(erc)//这里是while循环退出的地方 exit break return continue 等 有待完善
{
case PROC_SQL_RC_OK:
break;
case PROC_SQL_RC_EXIT:
break;
case PROC_SQL_RC_CONTINUE:
break;
case PROC_SQL_RC_RETURN:
break;
default:
break;
}
}
return 1;
}
public static int exec_stmt_case(ProcExecuteState estate,CaseNode casenode)
{
ExprNode val=null; //case expr 的那个变量的值 接下来每一个whennode 的expr和它做比较 如果为真就执行,否则就不执行
if(casenode.expr!=null)
{
//val=exec_eval_expr(estate,casenode.expr);
val=casenode.expr;
//exec_assign_value 在这里给变量赋值
}
for (Node item : casenode.case_list) {
WhenNode whennode=(WhenNode)item;
boolean value =exec_eval_compare(val,whennode.expr);
if(value)
{
return exec_stmts(estate, whennode.stmts);
}
}
if(casenode.have_else==1)
{
return exec_stmts(estate, casenode.else_stmts);
}
return 1;
}
public static int exec_stmt_sql(ProcExecuteState estate,StmtNode stmt)
{
return mysql.exec_update(stmt.str_sql);
}
//执行表达式,并返回结果
public static boolean exec_eval_bool(ProcExecuteState estate,ExprNode expr)
{
String sql=String.format("select %s", GetExprString(expr));//获取表达式字符串
return Integer.parseInt(mysql.exec(sql).toString())==1?true:false;//从数据库查询的到结果
}
public static boolean exec_eval_compare(ExprNode expr1,ExprNode expr2)
{
String sql1=String.format("select %s", GetExprString(expr1));//获取表达式字符串
String ret1=mysql.exec(sql1).toString();
String sql2=String.format("select %s", GetExprString(expr2));//获取表达式字符串
String ret2=mysql.exec(sql2).toString();
return ret1.equals(ret2);
}
public static int exec_eval_int(ProcExecuteState estate,ExprNode expr)
{
String sql=String.format("select %s", GetExprString(expr));
return Integer.parseInt(mysql.exec(sql).toString());
}
public static ExprNode exec_eval_expr(ProcExecuteState estate,ExprNode expr)
{
return null;
}
public static void add_var(String var_name,Dataum data)
{
if(!var_table.containsKey(var_name))
{
var_table.put(var_name, data);
}
}
public static void set_value(String var_name,Object value)
{
ExprNode v=(ExprNode)value;
Dataum data;
if(v.is_const==1)//是否常量 如果是常量就用常量值 否则就计算该表达式的值
data=new Dataum(v.data_type, v.const_value);
else
{
String sql=String.format("select %s", GetExprString(v));//获取表达式字符串
String ret=mysql.exec(sql).toString();//从数据库查询的到结果
data=new Dataum(v.data_type, ret);
}
if(!var_table.containsKey(var_name))
{
var_table.put(var_name, data);
}
else
{
var_table.remove(var_name);
var_table.put(var_name, data);
}
}
private static Dataum get_var_value(String var_name)
{
return (Dataum) var_table.get(var_name);
}
//获取该表达式节点的 字符串形式 还应该为里面的变量替换为真正的值
public static String expr_str="";
public static String GetExprString(ExprNode expr)
{
expr_str="";
InOrder(expr);
return expr_str;
}
//中序遍历表达式
private static void InOrder(ExprNode expr)
{
if(expr==null)
return;
if(expr.is_wrap==1)
expr_str+="(";
InOrder(expr.lnext);
if(expr.is_const==-1)//+ - * / % >>等
expr_str+=expr.sign;
else if(expr.is_const==1)
expr_str+=expr.const_value;
else if(expr.is_const==0)
{
Dataum data=get_var_value(expr.var_value.var_name);
if(data!=null)
{
expr_str+=data.value;
}
else
{
expr_str+=expr.var_value.var_name;
System.out.println(expr.var_value.var_name+" 未赋值");
}
}
InOrder(expr.rnext);
if(expr.is_wrap==1)
expr_str+=")";
}
public static void show_var()
{
Iterator iter = var_table.entrySet().iterator();
while(iter.hasNext())
{
Map.Entry<String, Object> entry = (Map.Entry<String, Object>) iter.next();
String key = entry.getKey();
Dataum data=(Dataum)entry.getValue();
System.out.println(key+" "+data.value);
}
}
}
可以看出来一个存储过程的执行基本上就是一个递归的过程
此博文的出处 为 http://blog.csdn.net/zhujunxxxxx/article/details/39251241如果进行转载请注明出处。本文作者原创,邮箱zhujunxxxxx@163.com,如有问题请联系作者
作者简介
作者是一名软件工程出生的苦逼程序员,本科阶段也是软件工程,目前研究生在读,热爱新技术,热爱编程,为人幽默,热爱开源。
个人网站:http://www.zhujuncoding.com/
github: https://github.com/zhujunxxxxx/
测试类
public class test3 {
public static void main(String[] args) {
DeclareNode d1=new DeclareNode();// 定义x 和 y两个变量
d1.node_type=NodeType.t_declare;
List<Node> list=new ArrayList<Node>();
VarNode var1=new VarNode();
var1.data_type=DataType.TT_INT;
var1.var_name="x";
VarNode var2=new VarNode();
var2.data_type=DataType.TT_INT;
var2.var_name="y";
list.add(var1);
list.add(var2);
d1.var_list=list;
SetNode set=new SetNode();
set.node_type=NodeType.t_set;
List<Node> setlist=new ArrayList<Node>();
VarNode svar=new VarNode(); //给x 赋值为 1 + 9
svar.data_type=DataType.TT_INT;
svar.var_name="x";
ExprNode expr=new ExprNode();
expr.is_const=-1;
expr.data_type=DataType.TT_SIGN;
expr.sign="+";
ExprNode l=new ExprNode();
l.is_const=1;
l.const_value="1";
l.data_type=DataType.TT_INT;
ExprNode r=new ExprNode();
r.is_const=1;
r.const_value="9";
r.data_type=DataType.TT_INT;
expr.lnext=l;
expr.rnext=r;
svar.expr_value=expr;
setlist.add(svar);
set.var_list=setlist;
/*
SetNode set_add=new SetNode();
set_add.node_type=NodeType.t_set;
List<Node> setlist_add=new ArrayList<Node>();
VarNode svar_add=new VarNode(); //给x 赋值为 11
svar_add.data_type=DataType.TT_INT;
svar_add.var_name="x";
ExprNode expr_add=new ExprNode();
expr_add.is_const=1;
expr_add.const_value="11";
svar_add.expr_value=expr_add;
setlist_add.add(svar_add);
set_add.var_list=setlist_add;
*/
SetNode set_add=new SetNode(); // x = x + 1
set_add.node_type=NodeType.t_set;
List<Node> setlist_add=new ArrayList<Node>();
VarNode svar_add=new VarNode(); // x =
svar_add.data_type=DataType.TT_INT;
svar_add.var_name="x";
ExprNode expr_add=new ExprNode();// x + 1
expr_add.is_const=-1;
expr_add.data_type=DataType.TT_SIGN;
expr_add.sign="+"; // +
ExprNode lexpr_add=new ExprNode();// x
lexpr_add.is_const=0;
lexpr_add.data_type=DataType.TT_INT;
VarNode var_add=new VarNode();
var_add.data_type=DataType.TT_INT;
var_add.var_name="x";
lexpr_add.var_value=var_add;
ExprNode rexpr_add=new ExprNode();// 1
rexpr_add.is_const=1;
rexpr_add.const_value="1";
rexpr_add.data_type=DataType.TT_INT;
expr_add.lnext=lexpr_add;
expr_add.rnext=rexpr_add;
svar_add.expr_value=expr_add; //x = expr
setlist_add.add(svar_add);
set_add.var_list=setlist_add;
//if(x>10)
ExprNode ifexpr=new ExprNode(); //定义一个 if 语句的expr 为x>10
ifexpr.is_const=-1;
ifexpr.sign=">";
ifexpr.is_wrap=1;
ifexpr.data_type=DataType.TT_SIGN;
ExprNode lexpr=new ExprNode();
lexpr.is_const=0;
lexpr.data_type=DataType.TT_INT;
VarNode var=new VarNode();
var.data_type=DataType.TT_INT;
var.var_name="x";
lexpr.var_value=var;
ExprNode rexpr=new ExprNode();
rexpr.is_const=1;
rexpr.const_value="10";
rexpr.data_type=DataType.TT_INT;
ifexpr.lnext=lexpr;
ifexpr.rnext=rexpr;
List<Node> thenlist=new ArrayList<Node>();
StmtNode sql=new StmtNode();
sql.node_type=NodeType.t_stmt;
sql.str_sql="insert into zz_test(name,age) values('true',10);";
thenlist.add(sql);
List<Node> elselist=new ArrayList<Node>();
StmtNode sql2=new StmtNode();
sql2.node_type=NodeType.t_stmt;
sql2.str_sql="insert into zz_test(name,age) values('false',20);";
elselist.add(sql2);
IfNode ifnode=new IfNode();
ifnode.node_type=NodeType.t_if;
ifnode.expr=ifexpr;
ifnode.then_body=thenlist;
ifnode.else_body=elselist;
ifnode.elseif_body=new ArrayList<Node>();//赋值为空list
//while ( x < 20)
WhileNode whilenode =new WhileNode();
whilenode.node_type=NodeType.t_while;
ExprNode whileexpr=new ExprNode();
whileexpr.is_const=-1;
whileexpr.sign="<";
whileexpr.is_wrap=1;
whileexpr.data_type=DataType.TT_SIGN;
ExprNode wlexpr=new ExprNode();
wlexpr.is_const=0;
wlexpr.data_type=DataType.TT_INT;
VarNode wvar=new VarNode();
wvar.data_type=DataType.TT_INT;
wvar.var_name="x";
wlexpr.var_value=wvar;
ExprNode wrexpr=new ExprNode();
wrexpr.is_const=1;
wrexpr.const_value="20";
wrexpr.data_type=DataType.TT_INT;
whileexpr.lnext=wlexpr;
whileexpr.rnext=wrexpr;
whilenode.expr=whileexpr;//设置while 的expe
List<Node> whilelist=new ArrayList<Node>();
StmtNode whilesql=new StmtNode();
whilesql.node_type=NodeType.t_stmt;
whilesql.str_sql="insert into zz_test(name,age) values('while',10);";
whilelist.add(whilesql);
whilelist.add(set_add);//x=x+1
whilenode.body=whilelist;//设置while的body
//case case
CaseNode casenode=new CaseNode();
//case x then
ExprNode caseexpr=new ExprNode();
caseexpr.is_const=0;
caseexpr.data_type=DataType.TT_VAR;
VarNode casevar=new VarNode();
casevar.data_type=DataType.TT_INT;
casevar.var_name="x";
caseexpr.var_value=casevar;
casenode.expr=caseexpr;//给casenode 赋值 表达式
casenode.node_type=NodeType.t_case;// 设置类型
casenode.have_else=0;
List<Node> caselist=new ArrayList<Node>();
WhenNode when1=new WhenNode();//设置一个when节点
ExprNode whenexpr1=new ExprNode();
whenexpr1.is_const=1;
whenexpr1.data_type=DataType.TT_INT;
whenexpr1.const_value="11";
when1.expr=whenexpr1;//设置when 11
List<Node> caselist_when1=new ArrayList<Node>();
StmtNode casesql_1=new StmtNode();
casesql_1.node_type=NodeType.t_stmt;
casesql_1.str_sql="insert into zz_test(name,age) values('when1',10);";
caselist_when1.add(casesql_1);
when1.stmts=caselist_when1;//设置 when1的执行语句
WhenNode when2=new WhenNode();
ExprNode whenexpr2=new ExprNode();
whenexpr2.is_const=1;
whenexpr2.data_type=DataType.TT_INT;
whenexpr2.const_value="12";
when2.expr=whenexpr2;
List<Node> caselist_when2=new ArrayList<Node>();
StmtNode casesql_2=new StmtNode();
casesql_2.node_type=NodeType.t_stmt;
casesql_2.str_sql="insert into zz_test(name,age) values('when2',10);";
caselist_when2.add(casesql_2);
when2.stmts=caselist_when2;
caselist.add(when1);
caselist.add(when2);
casenode.case_list=caselist;//设置caselist
List<Node> root=new ArrayList<Node>();
root.add(d1);//定义x , y
root.add(set);// 设置 x等于 1+9
root.add(ifnode); //设置条件 x>10 这时候 10>10 为fasle
//root.add(whilenode);
root.add(set_add);
root.add(set_add);// 设置 x等于 x = x + 1 11
//root.add(set_add);// 设置 x等于 x = x + 1 12
//root.add(set_add);// 设置 x等于 x = x + 1 13
//root.add(set_add);// 设置 x等于 x = x + 1 14
root.add(casenode);
//root.add(ifnode); //设置条件 x>10
ProcExecuteState estste=new ProcExecuteState();
language.exec_stmts(estste, root);
language.show_var();
}
}