mysql->sqlserver建表语句转换
This commit is contained in:
@@ -0,0 +1,113 @@
|
|||||||
|
package com.zyplayer.doc.db.framework.db.sql.dialect.mysql;
|
||||||
|
|
||||||
|
import com.alibaba.druid.DbType;
|
||||||
|
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||||
|
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
|
||||||
|
import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr;
|
||||||
|
import com.alibaba.druid.sql.ast.statement.*;
|
||||||
|
import com.alibaba.druid.sql.dialect.mysql.ast.MySqlPrimaryKey;
|
||||||
|
import com.alibaba.druid.sql.dialect.mysql.ast.MySqlUnique;
|
||||||
|
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlCreateTableStatement;
|
||||||
|
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlOutputVisitor;
|
||||||
|
import com.alibaba.druid.sql.parser.SQLParserUtils;
|
||||||
|
import com.zyplayer.doc.db.framework.db.sql.dialect.mysql.function.MySqlToSqlServerFunctionTransform;
|
||||||
|
import com.zyplayer.doc.db.framework.db.sql.dialect.mysql.util.MySqlSQLDataTypeTransformUtil;
|
||||||
|
import com.zyplayer.doc.db.framework.utils.MapCacheUtil;
|
||||||
|
import com.zyplayer.doc.db.framework.utils.SQLTransformUtils;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mysql转sqlserver遍历实现
|
||||||
|
*
|
||||||
|
* @author diantu
|
||||||
|
* @since 2023年2月6日
|
||||||
|
*/
|
||||||
|
public class MySqlToSqlServerOutputVisitor extends MySqlOutputVisitor {
|
||||||
|
|
||||||
|
private final MySqlToSqlServerFunctionTransform functionTransform = new MySqlToSqlServerFunctionTransform();
|
||||||
|
|
||||||
|
// 目标数据库类型
|
||||||
|
private final DbType distDbType = DbType.sqlserver;
|
||||||
|
|
||||||
|
public MySqlToSqlServerOutputVisitor(Appendable appender) {
|
||||||
|
super(appender);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MySqlToSqlServerOutputVisitor(Appendable appender, boolean parameterized) {
|
||||||
|
super(appender, parameterized);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mysql建表语句遍历
|
||||||
|
* @param x
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean visit(MySqlCreateTableStatement x) {
|
||||||
|
SQLCreateTableStatement sQLCreateTableStatement = new SQLCreateTableStatement();
|
||||||
|
sQLCreateTableStatement.setTableSource(x.getTableSource());
|
||||||
|
String tableName = x.getTableSource().getName().getSimpleName();
|
||||||
|
sQLCreateTableStatement.setName(String.valueOf(x.getName()).replaceAll("\"", ""));
|
||||||
|
sQLCreateTableStatement.setName(String.valueOf(x.getName()).replaceAll("`", ""));
|
||||||
|
sQLCreateTableStatement.setComment(x.getComment());
|
||||||
|
for(SQLTableElement sqlTableElement : x.getTableElementList()){
|
||||||
|
if( sqlTableElement instanceof SQLColumnDefinition) {
|
||||||
|
SQLColumnDefinition sqlColumnDefinition = ((SQLColumnDefinition)sqlTableElement);
|
||||||
|
String columnName = sqlColumnDefinition.getName().getSimpleName().replaceAll("\"", "");
|
||||||
|
columnName = columnName.replaceAll("`", "");
|
||||||
|
sqlColumnDefinition.setName(columnName);
|
||||||
|
if(SQLTransformUtils.containsKeyWords(columnName,DbType.sqlserver)){
|
||||||
|
sqlColumnDefinition.setName("\""+columnName+"\"");
|
||||||
|
}
|
||||||
|
sqlColumnDefinition.setDataType(MySqlSQLDataTypeTransformUtil.transformMySqlToSqlServer(SQLParserUtils.createExprParser(sqlColumnDefinition.getDataType().toString(), DbType.mysql).parseDataType()));
|
||||||
|
if(sqlColumnDefinition.getDefaultExpr() != null) {
|
||||||
|
SQLExpr expr = sqlColumnDefinition.getDefaultExpr();
|
||||||
|
if(expr instanceof SQLMethodInvokeExpr) {
|
||||||
|
functionTransform.methodInvoke((SQLMethodInvokeExpr) sqlColumnDefinition.getDefaultExpr());
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
//自增转换
|
||||||
|
if(sqlColumnDefinition.isAutoIncrement()){
|
||||||
|
sqlColumnDefinition.setAutoIncrement(false);
|
||||||
|
SQLColumnDefinition.Identity identity = new SQLColumnDefinition.Identity();
|
||||||
|
identity.setCycle(true);
|
||||||
|
identity.setIncrement(1);
|
||||||
|
sqlColumnDefinition.setIdentity(identity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//@TODO 注释待转换
|
||||||
|
if(sqlColumnDefinition.getComment()!= null){
|
||||||
|
sqlColumnDefinition.setComment((String) null);
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlColumnDefinition.setDbType(distDbType);
|
||||||
|
MapCacheUtil.getInstance().addCacheData(tableName.toUpperCase() + ":" + columnName.toUpperCase(), sqlColumnDefinition.toString().replaceAll(sqlColumnDefinition.getColumnName(), ""));
|
||||||
|
sQLCreateTableStatement.getTableElementList().add(sqlColumnDefinition);
|
||||||
|
}else if(sqlTableElement instanceof MySqlPrimaryKey){
|
||||||
|
SQLPrimaryKeyImpl sqlserverPrimaryKey = new SQLPrimaryKeyImpl();
|
||||||
|
List<SQLSelectOrderByItem> list = ((MySqlPrimaryKey) sqlTableElement).getIndexDefinition().getColumns();
|
||||||
|
for(int i=0;i<list.size();i++){
|
||||||
|
SQLIdentifierExpr sQLIdentifierExpr = (SQLIdentifierExpr)list.get(i).getExpr();
|
||||||
|
sQLIdentifierExpr.setName(sQLIdentifierExpr.getName().replaceAll("`", ""));
|
||||||
|
sqlserverPrimaryKey.addColumn(sQLIdentifierExpr);
|
||||||
|
}
|
||||||
|
sQLCreateTableStatement.getTableElementList().add(sqlserverPrimaryKey);
|
||||||
|
}else if(sqlTableElement instanceof MySqlUnique) {
|
||||||
|
SQLUnique sqlserverUnique = new SQLUnique();
|
||||||
|
((MySqlUnique) sqlTableElement).cloneTo(sqlserverUnique);
|
||||||
|
sQLCreateTableStatement.getTableElementList().add(sqlserverUnique);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(Objects.nonNull(x.getSelect())){
|
||||||
|
x.setParent(sQLCreateTableStatement);
|
||||||
|
sQLCreateTableStatement.setSelect(x.getSelect());
|
||||||
|
}
|
||||||
|
println();
|
||||||
|
print(sQLCreateTableStatement.toString());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -8,5 +8,5 @@ import com.zyplayer.doc.db.framework.db.sql.MethodInvoke;
|
|||||||
* @author diantu
|
* @author diantu
|
||||||
* @since 2023年1月29日
|
* @since 2023年1月29日
|
||||||
*/
|
*/
|
||||||
public interface MySqlFunction extends MethodInvoke {
|
public interface MySqlToOracleFunction extends MethodInvoke {
|
||||||
}
|
}
|
||||||
@@ -6,5 +6,5 @@ package com.zyplayer.doc.db.framework.db.sql.dialect.mysql.function;
|
|||||||
* @author diantu
|
* @author diantu
|
||||||
* @since 2023年1月29日
|
* @since 2023年1月29日
|
||||||
*/
|
*/
|
||||||
public class MySqlToOracleFunctionTransform implements MySqlFunction{
|
public class MySqlToOracleFunctionTransform implements MySqlToOracleFunction {
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,50 @@
|
|||||||
|
package com.zyplayer.doc.db.framework.db.sql.dialect.mysql.function;
|
||||||
|
|
||||||
|
import com.alibaba.druid.sql.ast.SQLObject;
|
||||||
|
import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr;
|
||||||
|
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
|
||||||
|
import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr;
|
||||||
|
import com.alibaba.druid.sql.ast.statement.SQLColumnDefinition;
|
||||||
|
import com.alibaba.druid.sql.ast.statement.SQLSelectItem;
|
||||||
|
import com.zyplayer.doc.db.framework.db.sql.MethodInvoke;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mysql2sqlserver需要转换的函数
|
||||||
|
*
|
||||||
|
* @author diantu
|
||||||
|
* @since 2023年2月6日
|
||||||
|
*/
|
||||||
|
public interface MySqlToSqlServerFunction extends MethodInvoke {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换 AUTO_INCREMENT 函数
|
||||||
|
* @author diantu
|
||||||
|
* @date 2023年2月6日
|
||||||
|
* @param expr
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
void auto_increment(SQLMethodInvokeExpr expr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 整体替换当前类型
|
||||||
|
* @author diantu
|
||||||
|
* @date 2023年2月6日
|
||||||
|
* @param name
|
||||||
|
* @param expr
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
default void identifierExpr(String name, SQLObject expr) {
|
||||||
|
SQLIdentifierExpr sqlIdentifierExpr = new SQLIdentifierExpr();
|
||||||
|
sqlIdentifierExpr.setName(name);
|
||||||
|
sqlIdentifierExpr.setParent(expr.getParent());
|
||||||
|
SQLObject parent = expr.getParent();
|
||||||
|
if (parent instanceof SQLSelectItem) {
|
||||||
|
((SQLSelectItem) parent).setExpr(sqlIdentifierExpr);
|
||||||
|
} else if (parent instanceof SQLBinaryOpExpr) {
|
||||||
|
((SQLBinaryOpExpr) parent).setRight(sqlIdentifierExpr);
|
||||||
|
}else if(parent instanceof SQLColumnDefinition){
|
||||||
|
((SQLColumnDefinition) parent).setName(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package com.zyplayer.doc.db.framework.db.sql.dialect.mysql.function;
|
||||||
|
|
||||||
|
import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mysql2sqlserver需要转换的函数实现
|
||||||
|
*
|
||||||
|
* @author diantu
|
||||||
|
* @since 2023年2月6日
|
||||||
|
*/
|
||||||
|
public class MySqlToSqlServerFunctionTransform implements MySqlToSqlServerFunction{
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void auto_increment(SQLMethodInvokeExpr expr) {
|
||||||
|
identifierExpr("identity", expr);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -13,13 +13,16 @@ import com.alibaba.druid.util.FnvHash;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* mysql sql转换工具类
|
* mysql sql字段类型转换工具类
|
||||||
*
|
*
|
||||||
* @author diantu
|
* @author diantu
|
||||||
* @since 2023年1月30日
|
* @since 2023年1月30日
|
||||||
*/
|
*/
|
||||||
public class MySqlSQLDataTypeTransformUtil extends SQLTransformUtils {
|
public class MySqlSQLDataTypeTransformUtil extends SQLTransformUtils {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MySql->Oracle字段类型转换
|
||||||
|
*/
|
||||||
public static SQLDataType transformMySqlToOracle(SQLDataType x) {
|
public static SQLDataType transformMySqlToOracle(SQLDataType x) {
|
||||||
final String name = x.getName();
|
final String name = x.getName();
|
||||||
final long nameHash = x.nameHashCode64();
|
final long nameHash = x.nameHashCode64();
|
||||||
@@ -101,4 +104,46 @@ public class MySqlSQLDataTypeTransformUtil extends SQLTransformUtils {
|
|||||||
|
|
||||||
return dataType;
|
return dataType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MySql->SqlServer字段类型转换
|
||||||
|
*/
|
||||||
|
public static SQLDataType transformMySqlToSqlServer(SQLDataType x) {
|
||||||
|
final String name = x.getName();
|
||||||
|
final long nameHash = x.nameHashCode64();
|
||||||
|
if (name == null) {
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
List<SQLExpr> argumentns = x.getArguments();
|
||||||
|
SQLDataType dataType;
|
||||||
|
if (nameHash == FnvHash.Constants.ENUM) {
|
||||||
|
argumentns.clear();
|
||||||
|
dataType = new SQLCharacterDataType("enum");
|
||||||
|
|
||||||
|
} else if(nameHash == FnvHash.Constants.SET){
|
||||||
|
argumentns.clear();
|
||||||
|
dataType = new SQLCharacterDataType("set");
|
||||||
|
|
||||||
|
}else if(nameHash == FnvHash.Constants.BIGINT){
|
||||||
|
dataType = new SQLCharacterDataType("bigint");
|
||||||
|
|
||||||
|
}else if(nameHash == FnvHash.Constants.INT){
|
||||||
|
dataType = new SQLCharacterDataType("int");
|
||||||
|
|
||||||
|
}else if(nameHash == FnvHash.Constants.TINYINT){
|
||||||
|
dataType = new SQLCharacterDataType("tinyint");
|
||||||
|
|
||||||
|
}else if(nameHash == FnvHash.Constants.SMALLINT){
|
||||||
|
dataType = new SQLCharacterDataType("smallint");
|
||||||
|
|
||||||
|
}else {
|
||||||
|
dataType = x;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dataType != x) {
|
||||||
|
dataType.setParent(x.getParent());
|
||||||
|
}
|
||||||
|
|
||||||
|
return dataType;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import com.zyplayer.doc.db.framework.db.sql.MethodInvoke;
|
|||||||
* @author diantu
|
* @author diantu
|
||||||
* @since 2023年1月29日
|
* @since 2023年1月29日
|
||||||
*/
|
*/
|
||||||
public interface OracleFunction extends MethodInvoke {
|
public interface OracleToMySqlFunction extends MethodInvoke {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 转换 sys_guid 函数
|
* 转换 sys_guid 函数
|
||||||
@@ -8,7 +8,7 @@ import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr;
|
|||||||
* @author diantu
|
* @author diantu
|
||||||
* @since 2023年1月29日
|
* @since 2023年1月29日
|
||||||
*/
|
*/
|
||||||
public class OracleToMySqlFunctionTransform implements OracleFunction{
|
public class OracleToMySqlFunctionTransform implements OracleToMySqlFunction {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sys_guid(SQLMethodInvokeExpr expr) {
|
public void sys_guid(SQLMethodInvokeExpr expr) {
|
||||||
|
|||||||
@@ -15,13 +15,16 @@ import java.util.List;
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* oracle sql转换工具类
|
* oracle sql字段类型转换工具类
|
||||||
*
|
*
|
||||||
* @author diantu
|
* @author diantu
|
||||||
* @since 2023年1月29日
|
* @since 2023年1月29日
|
||||||
*/
|
*/
|
||||||
public class OracleSQLDataTypeTransformUtil extends SQLTransformUtils {
|
public class OracleSQLDataTypeTransformUtil extends SQLTransformUtils {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Oracle->MySql字段类型转换
|
||||||
|
*/
|
||||||
public static SQLDataType transformOracleToMySql(SQLDataType x) {
|
public static SQLDataType transformOracleToMySql(SQLDataType x) {
|
||||||
final String name = x.getName();
|
final String name = x.getName();
|
||||||
final long nameHash = x.nameHashCode64();
|
final long nameHash = x.nameHashCode64();
|
||||||
|
|||||||
@@ -8,6 +8,6 @@ import com.zyplayer.doc.db.framework.db.sql.MethodInvoke;
|
|||||||
* @author diantu
|
* @author diantu
|
||||||
* @since 2023年2月2日
|
* @since 2023年2月2日
|
||||||
*/
|
*/
|
||||||
public interface SqlServerFunction extends MethodInvoke{
|
public interface SqlServerToMySqlFunction extends MethodInvoke{
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -6,6 +6,6 @@ package com.zyplayer.doc.db.framework.db.sql.dialect.sqlserver.function;
|
|||||||
* @author diantu
|
* @author diantu
|
||||||
* @since 2023年2月2日
|
* @since 2023年2月2日
|
||||||
*/
|
*/
|
||||||
public class SqlServerToMySqlFunctionTransform implements SqlServerFunction {
|
public class SqlServerToMySqlFunctionTransform implements SqlServerToMySqlFunction {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,13 +10,16 @@ import com.alibaba.druid.util.FnvHash;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* sqlserver sql转换工具类
|
* sqlserver sql字段类型转换工具类
|
||||||
*
|
*
|
||||||
* @author diantu
|
* @author diantu
|
||||||
* @since 2023年2月2日
|
* @since 2023年2月2日
|
||||||
*/
|
*/
|
||||||
public class SqlServerSQLDataTypeTransformUtil extends SQLTransformUtils {
|
public class SqlServerSQLDataTypeTransformUtil extends SQLTransformUtils {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SqlServer->MySql字段类型转换
|
||||||
|
*/
|
||||||
public static SQLDataType transformSqlServerToMySql(SQLDataType x) {
|
public static SQLDataType transformSqlServerToMySql(SQLDataType x) {
|
||||||
final String name = x.getName();
|
final String name = x.getName();
|
||||||
final long nameHash = x.nameHashCode64();
|
final long nameHash = x.nameHashCode64();
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import com.alibaba.druid.sql.dialect.sqlserver.parser.SQLServerLexer;
|
|||||||
import com.alibaba.druid.sql.parser.Keywords;
|
import com.alibaba.druid.sql.parser.Keywords;
|
||||||
import com.alibaba.druid.sql.parser.Lexer;
|
import com.alibaba.druid.sql.parser.Lexer;
|
||||||
import com.zyplayer.doc.db.framework.db.sql.dialect.mysql.MySqlToOracleOutputVisitor;
|
import com.zyplayer.doc.db.framework.db.sql.dialect.mysql.MySqlToOracleOutputVisitor;
|
||||||
|
import com.zyplayer.doc.db.framework.db.sql.dialect.mysql.MySqlToSqlServerOutputVisitor;
|
||||||
import com.zyplayer.doc.db.framework.db.sql.dialect.oracle.OracleToMySqlOutputVisitor;
|
import com.zyplayer.doc.db.framework.db.sql.dialect.oracle.OracleToMySqlOutputVisitor;
|
||||||
import com.zyplayer.doc.db.framework.db.sql.dialect.sqlserver.SqlServerToMySqlOutputVisitor;
|
import com.zyplayer.doc.db.framework.db.sql.dialect.sqlserver.SqlServerToMySqlOutputVisitor;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
@@ -81,6 +82,24 @@ public class SQLTransformUtils {
|
|||||||
return oracleSql;
|
return oracleSql;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mysql sql语句转换为sqlserver sql语句
|
||||||
|
* @param sql
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static String translateMySqlToSqlServer(String sql) {
|
||||||
|
List<SQLStatement> stmtList = SQLUtils.toStatementList(sql, DbType.mysql);
|
||||||
|
StringBuilder out = new StringBuilder();
|
||||||
|
MySqlToSqlServerOutputVisitor visitor = new MySqlToSqlServerOutputVisitor(out, false);
|
||||||
|
|
||||||
|
for(int i = 0; i < stmtList.size(); ++i) {
|
||||||
|
((SQLStatement)stmtList.get(i)).accept(visitor);
|
||||||
|
}
|
||||||
|
|
||||||
|
String sqlserverSql = out.toString();
|
||||||
|
return sqlserverSql;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 将字CLOB转成STRING类型
|
* 将字CLOB转成STRING类型
|
||||||
* @param clob
|
* @param clob
|
||||||
|
|||||||
@@ -114,7 +114,8 @@ public class MysqlServiceImpl extends DbBaseService {
|
|||||||
String mysqlSql = tableDdlList.get(0).get("Create Table") + ";";
|
String mysqlSql = tableDdlList.get(0).get("Create Table") + ";";
|
||||||
tableDdlVo.setMysql(mysqlSql);
|
tableDdlVo.setMysql(mysqlSql);
|
||||||
tableDdlVo.setOracle(SQLTransformUtils.translateMySqlToOracle(mysqlSql));
|
tableDdlVo.setOracle(SQLTransformUtils.translateMySqlToOracle(mysqlSql));
|
||||||
// TODO sqlserver等数据库同理
|
tableDdlVo.setSqlserver(SQLTransformUtils.translateMySqlToSqlServer(mysqlSql));
|
||||||
|
// TODO 其他数据库同理
|
||||||
}
|
}
|
||||||
return tableDdlVo;
|
return tableDdlVo;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user