当前位置: 代码迷 >> SQL >> JavaCC初探-T-SQL变换为P-SQL
  详细解决方案

JavaCC初探-T-SQL变换为P-SQL

热度:40   发布时间:2016-05-05 12:13:41.0
JavaCC初探-T-SQL转换为P-SQL

? ? ? ? ?前段时间,研究数据库迁移工作,使用Powerdesigner实现了数据库对象之间的转换,但是由于项目中使用了大量的存储过程、函数和触发器等,想着怎么实现这些代码的迁移,网上搜了一通,大概有两个工具(SQLWays和SwisSQL,具体可以百度),后来也使用了一种工具,但是转换效果不是特别好,需要手工重新修改。这些都是后话;还有一个思路,就是使用javaCC进行在词法语法级别进行转换。首先将T-SQL进行词法分析,语法分析,最后按照P-SQL语法规则进行重新生成。由于时间进度和难度,我也只是简单识别了一些语句,下面写个简单例子,以后有时间继续研究。javaCC的安装不再叙述,附件中是安装文件和示例;

需要转换的语句:

CREATE   FUNC  test(@pdata varchar(20), @pint int(10))   RETURN  varchar(30)

?在Eclipse建立一个文件sql.jj,注意规则里面的符号都是全英文状态下的

/** * JavaCC file */ options {  JDK_VERSION = "1.5";  STATIC = true ; //生成非静态类  LOOKAHEAD=1;//向前看2个字母,消除歧义用的  DEBUG_PARSER = true;//以debug形式生成,便于调试 }PARSER_BEGIN(eg1)package cn.heu.javacct.sql;import java.lang.StringBuffer; import java.io.StringReader; import java.io.Reader;public class eg1 {	private static StringBuffer sqlSB; 			public eg1(String s){	this((Reader)(new StringReader(s))); 	sqlSB = new StringBuffer();	}	 public String getSQL()     {         return sqlSB.toString();     }          public String convert(){    	String temp="";    	try 		{           temp= convertSQL();		}       catch(Exception e)         {             e.printStackTrace();         }        return temp;     }            public static void main(String args[]) throws ParseException {  	  	eg1 parser =null;    try         {                 String query = "  -- "+               " CREATE   FUNC  test(@pdata varchar(20),@pint int(10))   RETURN  varchar(30) ";                parser = new eg1(query);      		  //  parser.convert();       		    System.out.println("OLDSQL:"+query);                System.out.println("SQL:"+ parser.convert());                                }         catch(Exception e)         {               e.printStackTrace();         } }}PARSER_END(eg1)SKIP :{ 	" "|	"\r"|	"\t"|	"\n"|   "--"} TOKEN:/* ms SQL keywords*/{   < CREATE:" CREATE "|" create " >  |< ALTER:" ALTER "|" alter " >  |< FROM : " from " >   |< FUNCNAME:<FUNCNAME> >  |< FUNCTION :" FUNC "|" FUNCTION "|" func "|" function " >    |< PROCEDURE:" PROCEDURE "|" PROC "|" procedure "|" proc " >  |< RETURN:" RETURN "|" return " >  |< _begin:" begin "|" BEGIN " >  |< _end:" end "|" END " >  |< #FUNCNAME :(["0" - "9","A" - "Z","a" - "z"])+ >}TOKEN:/* ms SQL datatype */{	    < VARCHAR:"varchar("<NUM>")" >   |< INT:"int"<NUM> >   |< #NUM:(["0" - "9"])+>}TOKEN:{   <papams:"("(<PARAM>|<PARAM>","<PARAM>|<PARAM>(","<PARAM>",")+<PARAM>)")"  >  |<#PARAM:<p_data>" "<p_type>>  |<#p_data:(["0" - "9","A" - "Z","a" - "z","@"])+>  |<#p_type:<p_varchar>|<p_int>>  |<#p_varchar:"varchar("<p_NUM>")">  |<#p_int:"int("<p_NUM>")" >  |<#p_NUM:(["0" - "9"])+>}String convertSQL():{  Token t;  String temp="";  StringBuffer sb=new StringBuffer();}{    (    <CREATE>   <FUNCTION>      t=<FUNCNAME>   {     sb.append(" create or replace function  " );     sb.append(" "+t.image+" ");   }    t= <papams>     {    sb.append(t.image.replace("@",""));    }      t= <RETURN>      {   	sb.append(" "+t.image+" ");   }    t=<VARCHAR>    {   	sb.append(" "+t.image+" ");   }   )*   {     return sb.toString();   }} 

?建立完文件后,javaCC会自动生成相关的类

如下:


?

打开eg1.java,执行即可;

OLDSQL:  --  CREATE   FUNC  test(@pdata varchar(20),@pint int(10))   RETURN  varchar(30) Call:   convertSQL  Consumed token: <<CREATE>: " CREATE " at line 1 column 6>  Consumed token: <<FUNCTION>: " FUNC " at line 1 column 15>  Consumed token: <<FUNCNAME>: "test" at line 1 column 22>  Consumed token: <<papams>: "(@pdata varchar(20),@pint int(10))" at line 1 column 26>  Consumed token: <<RETURN>: " RETURN " at line 1 column 62>  Consumed token: <<VARCHAR>: "varchar(30)" at line 1 column 71>Return: convertSQLSQL: create or replace function   test (pdata varchar(20),pint int(10))  RETURN   varchar(30) 

?可见已经正常识别了!

?

如需扩展,还需深入研究,看见官方例子,该软件还是很强大的
?

  相关解决方案