Oracle uses functions to realize oracle table to generate mysql table DDL

1. Application background

Data migration is often used in work, especially the different types of databases have inconsistent table building syntax. The following is the output of MySQL table building DDL through the oracle function.

2. Function realization

1. Code

create or replace function fn_crea_tab_oracle2mysql
( i_owner                       in string,
  i_table_name                  in string,
  i_number_default_type         in string := 'decimal',
  i_auto_incretment_column_name in string := 'ID' -- '%ID'
)
  /*
  功能:ORACLE表生成MYSQL建表DDL
  参数说明:
  i_owner:schema名
  i_table_name:表名
  i_number_default_type:NUMBER默认转换的类型,缺省是decimal
  i_auto_incretment_column_name:自增属性字段名称规则,默认是ID,可传进来已知的自增字段

  已知问题:
  1.不支持分区
  2.不支持函数索引,位图索引等特殊索引定义
  3.不支持自定义数据类型,不支持ROWID,RAW等特殊数据类型
  4.不支持外键
  5.不支持自定义约束
  6.不支持与空间、事务相关属性
  7.DATE与TIMESTAMP转换成datetime,需注意精度
  8.超大NUMBER直接转换为bigint,需注意精度
  9.auto incretment 是根据字段名规则加一些判断,设置不一定准确,需检查
  */
 return clob is
  Result         clob;
  cnt            number;
  data_type      varchar2(128);
  column_str     varchar2(4000);
  table_comments varchar2(4000);
  is_pk_column   number := 0;
begin
  select count(*) into cnt
    from all_tables
   where owner = upper(i_owner)
     and table_name = upper(i_table_name);
  if (cnt = 0) then
    RAISE_APPLICATION_ERROR(-20000,'can not found table,please check input!');
  else
    Result := 'CREATE TABLE `' || lower(i_table_name) || '`(';
    /*
    字段数据类型
    */
    for c in (select a.column_name,
                     a.data_type,
                     a.data_length,
                     a.data_precision,
                     a.data_scale,
                     a.nullable,
                     a.data_default,
                     b.COMMENTS
                from all_tab_cols a, all_col_comments b
               where a.owner = upper(i_owner)
                 and a.table_name = upper(i_table_name)
                 and a.HIDDEN_COLUMN = 'NO'
                 and a.owner = b.OWNER
                 and a.TABLE_NAME = b.TABLE_NAME
                 and a.COLUMN_NAME = b.COLUMN_NAME
               order by a.column_id) loop
      if (c.data_type = 'VARCHAR2' or c.data_type = 'NVARCHAR2') then
        data_type := 'varchar(' || c.data_length || ')';
      elsif (c.data_type = 'CHAR' or c.data_type = 'NCHAR') then
        data_type := 'char(' || c.data_length || ')';
      elsif (c.data_type = 'NUMBER') then
        if (c.data_precision is not null and (c.data_scale = 0 or c.data_scale is null) ) then
          data_type := 'int(' || c.data_precision || ')';
        elsif (c.data_precision is not null and c.data_scale is not null) then
          data_type := 'decimal(' || c.data_precision || ',' || c.data_scale || ')';
        else
          data_type := i_number_default_type;
        end if;
      elsif (c.data_type = 'DATE' or c.data_type like 'TIMESTAMP%') then
        data_type := 'datetime';
      elsif (c.data_type = 'CLOB' or c.data_type = 'NCLOB' or
            c.data_type = 'LONG') then
        data_type := 'text';
      elsif (c.data_type = 'BLOB' or c.data_type = 'LONG RAW') then
        data_type := 'blob';
      elsif (c.data_type = 'BINARY_FLOAT') then
        data_type := 'float';
      elsif (c.data_type = 'BINARY_DOUBLE') then
        data_type := 'double';
      else
        data_type := c.data_type;
      end if;
      
      column_str := '  `' || lower(c.column_name) || '` ' || data_type;
      
    /*
    自增主键:id列视为自增id列
    */
      if (c.column_name = upper(i_auto_incretment_column_name) and
         (c.data_scale is null or c.data_scale = 0)) then
        select count(*)
          into is_pk_column
          from all_constraints a, all_cons_columns b
         where a.owner = upper(i_owner)
           and a.table_name = upper(i_table_name)
           and a.constraint_type = 'P'
           and a.OWNER = b.OWNER
           and a.TABLE_NAME = b.TABLE_NAME
           and a.CONSTRAINT_NAME = b.CONSTRAINT_NAME
           and b.COLUMN_NAME = c.column_name;
        if is_pk_column > 0 then
          column_str := column_str || ' AUTO_INCREMENT';
        end if;
      end if;
    /*
    字段是否可为空
    */
      if c.nullable = 'N' then
        column_str := column_str || ' NOT NULL';
      end if;
      if (trim(c.data_default) is not null) then
        column_str := column_str || ' DEFAULT ' ||
                      trim(replace(replace(c.data_default, chr(13), ''),
                                   chr(10),
                                   ''));
      end if;
    /*
    字段注释
    */
      if c.comments is not null then
        column_str := column_str || ' COMMENT ''' || c.comments || '''';
      end if;
    /*
    结果组装
    */
      Result := Result || chr(10) || column_str || ',';
    end loop;
    
    /*
    主键
    */
    for c in (select a.constraint_name, wm_concat(a.column_name) pk_columns
                from (select a.CONSTRAINT_NAME,
                             '`' || b.COLUMN_NAME || '`' column_name
                        from all_constraints a, all_cons_columns b
                       where a.owner = upper(i_owner)
                         and a.table_name = upper(i_table_name)
                         and a.constraint_type = 'P'
                         and a.OWNER = b.OWNER
                         and a.TABLE_NAME = b.TABLE_NAME
                         and a.CONSTRAINT_NAME = b.CONSTRAINT_NAME
                       order by b.POSITION) a
               group by a.constraint_name) loop
      Result := Result || chr(10) || '  PRIMARY KEY (' ||
                lower(c.pk_columns) || '),';
    end loop;
    
    /*
    唯一键
    */
    for c in (select a.constraint_name, wm_concat(a.column_name) uk_columns
                from (select a.CONSTRAINT_NAME,
                             '`' || b.COLUMN_NAME || '`' column_name
                        from all_constraints a, all_cons_columns b
                       where a.owner = upper(i_owner)
                         and a.table_name = upper(i_table_name)
                         and a.constraint_type = 'U'
                         and a.OWNER = b.OWNER
                         and a.TABLE_NAME = b.TABLE_NAME
                         and a.CONSTRAINT_NAME = b.CONSTRAINT_NAME
                       order by b.POSITION) a
               group by a.constraint_name) loop
      Result := Result || chr(10) || '  UNIQUE KEY `' ||
                lower(c.constraint_name) || '`(' || lower(c.uk_columns) || '),';
    end loop;
    
    /*
    索引
    */
    for c in (select a.index_name, wm_concat(a.column_name) ind_columns
                from (select a.index_name,
                             '`' || a.COLUMN_NAME || '`' column_name
                        from all_ind_columns a
                       where a.table_owner = upper(i_owner)
                         and a.TABLE_NAME = upper(i_table_name)
                         and not exists
                       (select index_name
                                from all_constraints b
                               where a.TABLE_OWNER = b.owner
                                 and a.TABLE_NAME = b.TABLE_NAME
                                 and a.INDEX_NAME = b.INDEX_NAME)
                       order by a.COLUMN_POSITION) a
               group by a.index_name) loop
      Result := Result || chr(10) || '  KEY `' || lower(c.index_name) || '`(' ||
                lower(c.ind_columns) || '),';
    end loop;
    
    Result := substr(Result, 1, length(result) - 1) || chr(10) || ')';
    
    /*
    表注释
    */
    select max(a.COMMENTS)
      into table_comments
      from all_tab_comments a
     where owner = upper(i_owner)
       and table_name = upper(i_table_name);
    if (table_comments is not null) then
      Result := Result || 'COMMENT=''' || table_comments || '''';
    end if;
    
    Result := Result || ';';
  end if;
  return(Result);
end fn_crea_tab_oracle2mysql;

2. Effect
insert image description here

3. References

ORACLE table generates MYSQL table DDL

Guess you like

Origin blog.csdn.net/shammy_feng/article/details/123739104