Oracle数据库批量变更字段类型的实现步骤

 更新时间:2024年02月22日 09:14:14   作者:高彬  
我有个项目使用Oracle数据库,运行几年后数据量较大,需要对数据库做一次优化,其中有些字段类型类型需要调整,这里分享一下实现步骤,感兴趣的朋友可以参考下

场景:

我有个项目使用Oracle数据库,运行几年后数据量较大,需要对数据库做一次优化,其中有些字段类型类型需要调整,这里分享一下实现步骤。

思路:

首先大家要知道Oracle数据库不允许修改有数据表的的字段类型,经过分析我选择下面的方式实现修改字段类型:

1、如果原字段叫A ,则创建一个新字段(A2);

2、把原字段(A)的数据更新到A2;

3、删除原字段A;

4、把A2改名为A;

 以上是思路,以下是操作步骤 :

操作步骤

第1步、因为阻止修改做了约束的字段,因此先删除所有约束,在删除之前我们要备份好约束,调整完数据类型还要还原约束。

-- 生成索引
SELECT T.TABLE_NAME, --表名
T.INDEX_NAME, --索引名
I.UNIQUENESS, --是否非空
I.INDEX_TYPE, --索引类型
C.CONSTRAINT_TYPE, --键类型
WM_CONCAT(T.COLUMN_NAME) COLS,
 
'ALTER TABLE ' || T.TABLE_NAME || ' DROP CONSTRAINT ' || T.INDEX_NAME ||';' 删除索引 ,
 
(CASE
WHEN C.CONSTRAINT_TYPE = 'P' OR C.CONSTRAINT_TYPE = 'R' THEN --主键和外键创建脚本拼接
'ALTER TABLE ' || T.TABLE_NAME || ' ADD CONSTRAINT ' ||
T.INDEX_NAME || (CASE
WHEN C.CONSTRAINT_TYPE = 'P' THEN
' PRIMARY KEY ('
ELSE
' FOREIGN KEY ('
END) || WM_CONCAT(T.COLUMN_NAME) || ');'
ELSE --索引创建脚本拼接
'CREATE ' || (CASE
WHEN I.UNIQUENESS = 'UNIQUE' THEN
I.UNIQUENESS || ' '
ELSE
CASE
WHEN I.INDEX_TYPE = 'NORMAL' THEN
''
ELSE
I.INDEX_TYPE || ' '
END
END) || 'INDEX ' || T.INDEX_NAME || ' ON ' || T.TABLE_NAME || '(' ||
WM_CONCAT(COLUMN_NAME) || ');'
END) 添加索引 
FROM USER_IND_COLUMNS T, USER_INDEXES I, USER_CONSTRAINTS C
WHERE T.INDEX_NAME = I.INDEX_NAME
AND T.INDEX_NAME = C.CONSTRAINT_NAME(+)--自建表规则(只查询自己创建的表【我的建表规则以TB_开头】,排除系统表)
AND I.INDEX_TYPE != 'FUNCTION-BASED NORMAL' --排除基于函数的索引
GROUP BY T.TABLE_NAME,
T.INDEX_NAME,
I.UNIQUENESS,
I.INDEX_TYPE,
C.CONSTRAINT_TYPE;
 

上面的sql会生成“删除索引”和“添加索引”,   执行 删除索引  中的语句会删掉库中的所有约束。

第2步:生成修改字段类型的sql

 
select 
 x."fieldType",
'alter table '||x."tableName"||' add '||c.column_name||'_U2 '||
case LOWER(x."fieldType")
when 'dateTime' then 'date'  
when 'decimal'  then 'number(18,2)'
when 'tring'  then 'VARCHAR2(100)'
when 'int16'  then 'number(5)'
when 'int'  then 'number(9)'
when 'int32'  then 'number(9)'
when 'int64'  then 'number(19)'
else  '异常类型'
end ||';
update '||x."tableName"||' set '||c.column_name||'_U2='|| case when  c.column_name ='ZFID' then f_tonumber(SUBSTR(ZFID, 1,8)) else  c.column_name end  ||';
alter table '||x."tableName"||'  drop column '||c.column_name||';
alter table '||x."tableName"||' rename column '||c.column_name||'_U2 to '||c.column_name||';' s,
 
-- 'alter table '||x."tableName"||' modify '||x."fieldName"||' varchar2(50);' sql,
x."id",x."fieldName" , x."tableName",lower( c.data_type) 表类型,
lower(case when to_char( x."fieldType") like 'E_%' then 'int' else x."fieldType" end ) 实体类型,
x."fieldName",x."className",x."nameSpace",x."createDate" 
from user_tab_columns  c  
inner join XT_CLASS x 
on c.table_name = x."tableName" and c.column_name = x."fieldName"
where  1=1 and X."nameSpace"='RCSCloud.Models'  and  lower(x."tableName") not like 'v_%'

上面sql中用到的  xt_class是目标字段类型,我是从实体类中使用代码生成到xt_class表里的,这个过程需要您自己实现,xt_class表结构如下:

CREATE TABLE "XT_CLASS" 
   (	"tableName" VARCHAR2(50) NOT NULL ENABLE, 
	"fieldName" VARCHAR2(50) NOT NULL ENABLE, 
	"fieldTitle" VARCHAR2(255), 
	"fieldType" VARCHAR2(50), 
	"className" VARCHAR2(50), 
	"nameSpace" VARCHAR2(255), 
	"createDate" DATE, 
	"id" NUMBER(11,0) NOT NULL ENABLE
   ) SEGMENT CREATION IMMEDIATE 
  PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING
  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "IOTDATA"

第3步:把第2步生成的sql执行完 数据类型就调整好了,最后把第1步生成的“添加约束"的sql执行一遍 就完成了。

最后

到此这篇关于Oracle数据库批量变更字段类型的实现步骤的文章就介绍到这了,更多相关Oracle批量变更字段类型内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • ORACLE查询表最近更改数据的方法

    ORACLE查询表最近更改数据的方法

    修改项目时,涉及到了Oracle中许多表的修改(包括:增加、删除字段,修改注释等)。由于开始没有进行记录,造成在上测试机时,忘记了具体修改过哪些表了
    2012-11-11
  • Windows server 2019安装Oracle 19c的图文教程

    Windows server 2019安装Oracle 19c的图文教程

    Oracle是是一款高效、可靠、吞吐量高的数据库,本文主要介绍了Windows server 2019安装Oracle 19c的图文教程,具有一定的参考价值,感兴趣的可以了解一下
    2024-04-04
  • Oracle PL/SQL入门案例实践

    Oracle PL/SQL入门案例实践

    Oracle PL/SQL入门案例实践...
    2007-03-03
  • Oracle 游标使用总结

    Oracle 游标使用总结

    游标(CURSOR)也叫光标,在关系数据库中经常使用,在PL/SQL程序中可以用CURSOR与SELECT一起对表或者视图中的数据进行查询并逐行读取。
    2009-10-10
  • oracle 存储过程、函数和触发器用法实例详解

    oracle 存储过程、函数和触发器用法实例详解

    这篇文章主要介绍了oracle 存储过程、函数和触发器用法,结合实例形式详细分析了oralce 存储过程、函数和触发器具体功能、原理、定义、使用方法及相关操作注意事项,需要的朋友可以参考下
    2020-02-02
  • Oracle中获取执行计划的几种方法分析

    Oracle中获取执行计划的几种方法分析

    以下是对Oracle中获取执行计划的几种方法进行了详细的分析介绍,需要的朋友可以参考下
    2013-07-07
  • oracle 提示登录密码过期完美解决方法

    oracle 提示登录密码过期完美解决方法

    这篇文章主要介绍了oracle 提示登录密码过期完美解决方法,在文中给大家补充介绍了Oracle使用scott用户登录提示密码过期问题,需要的朋友参考下
    2018-04-04
  • 详解Oracle数据库中自带的所有表结构(sql代码)

    详解Oracle数据库中自带的所有表结构(sql代码)

    这篇文章主要介绍了Oracle数据库中自带的所有表结构,本文给大家介绍的非常详细,代码简单易懂,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-11-11
  • Oracle数据IMP和EXP命令用法详解

    Oracle数据IMP和EXP命令用法详解

    这篇文章主要给大家介绍了关于Oracle数据IMP和EXP命令用法详解的相关资料,我们可以使用Oracle自带的exp、imp命令来进行数据库备份,imp和exp称之为导入导出,这种方式也能快速的导入导出table或数据库,需要的朋友可以参考下
    2023-11-11
  • Oracle表空间详解

    Oracle表空间详解

    这篇文章主要介绍是Oracle表空间管理,文章中有详细的代码示例,对学习有一定的帮助,感兴趣的小伙伴可以参考一下
    2023-04-04

最新评论