暂无图片
暂无图片
1
暂无图片
暂无图片
暂无图片

Oracle_SQL审核_ALTER TABLE - MODIFY COLUMN

原创 1001 2024-05-07
436

语法

ALTER TABLE 'owner'.'tabname' MODIFY 'colname' [ 'coltype(length)' [DEFAULT] [CONSTRAINT] | VISIBLE ];

语法示例

SQL> create table scott.emp(empno number(8),empname varchar2(32));
SQL> desc emp
 Name                                                  Null?    Type
 ----------------------------------------------------- -------- ------------------------------------
 EMPNO                                                          NUMBER(8)
 EMPNAME                                                        VARCHAR2(32)

ALTER TABLE scott.emp MODIFY empno number(12);
ALTER TABLE scott.emp MODIFY (empno number(12),empname varchar2(64)...);
ALTER TABLE scott.emp MODIFY empno number(12) DEFAULT 0;
ALTER TABLE scott.emp MODIFY empno number(12) NOT NULL;
ALTER TABLE scott.emp MODIFY empno number(12) DEFAULT 0 NULL;
ALTER TABLE scott.emp MODIFY empno INVISIBLE;

概述

字段变更的需求看起来比较简单,但实际上,存在不少的坑;
除了变更字段的类型长度是否合理外,还需要考虑以下几方面:

  • 通常只允许扩大字段长度,不建议缩小缩小长度;
  • 需要确定是否只需要变更列出来的表中的字段;
  • 如果涉及到CHAR,VARCHAR2的字符类型的转变,需要确认业务中是否需要对字段长度进行判定;
  • 给字段新增默认值时,原字段中字段值不会受影响,不能通过扩字段时新增默认值来处理字段中的NULL值;

1、缩小字段长度

SQL> insert into scott.emp values('12345678','xiaoming'); 
SQL> ALTER TABLE scott.emp modify(empno number(6));

ORA-01440: column to be modified must be empty to decrease precision or scale

SQL> select max(length(empno)) from scott.emp;

MAX(LENGTH(EMPNO))
------------------
                 8

缩小字段长度不能小于表中字段的最大长度,否则会导致报错,一般不建议;

2、还有其他表中的字段也需要变更

业务上常用到的字段,都不会只存在于单一的表中,在很多表中都会存在,
因此有扩字段的需求时,需要考虑提供过来审核的变更脚本中,需要变更的表是否全面。

通过SQL,查出用户下的同名字段,看看是否都包含在变更脚本中,没包含在其中的需
要反馈给业务,判断是否需要一起变更。

SQL> create table scott.dept(deptno char(4),empname varchar2(32));
SQL> @same_cols
Enter value for owner: SCOTT
Enter value for column_name: EMPNAME

Table                          Column
Name                           Name                           DATA_TYPE                      DATA_LENGTH
------------------------------ ------------------------------ ------------------------------ -----------
EMP                            EMPNAME                        VARCHAR2                                32
DEPT                           EMPNAME                        VARCHAR2                                32
#SQL脚本 same_cols.sql
select table_name,column_name,data_type,data_length 
  from dba_tab_columns
 where owner = upper('&owner') and column_name=upper('&column_name')
 group by table_name,column_name,data_type,data_length
 order by table_name desc;

3、定长,变长字符类型的转变

char -> varchar2

char类型是定长,会给长度不够的字符串后面填充空格;
字段类型从char转变为varchar2时,已经被填充空格的字段值不会去掉空格;

SQL> insert into scott.dept values('010','xiaoming');
SQL> desc scott.dept 
 Name                                                  Null?    Type
 ----------------------------------------------------- -------- ------------------------------------
 DEPTNO                                                         CHAR(4)
 EMPNAME                                                        VARCHAR2(32)

SQL> select length(deptno) from scott.dept where empname='xiaoming';

LENGTH(DEPTNO)
--------------
             4

SQL> alter table scott.dept modify deptno varchar2(4);
SQL> desc scott.dept 
 Name                                                  Null?    Type
 ----------------------------------------------------- -------- ------------------------------------
 DEPTNO                                                         VARCHAR2(4)
 EMPNAME                                                        VARCHAR2(32)
SQL> select length(deptno) from scott.dept where empname='xiaoming';

LENGTH(DEPTNO)
--------------
             4

varchar2 -> char

字段类型从varchar2转变为char时,长度不足的字段值会被填充上空格;
使用length()来获取字段值长度时,会发现长度已经改变;

SQL> desc scott.dept
 Name                                                  Null?    Type
 ----------------------------------------------------- -------- ------------------------------------
 DEPTNO                                                         VARCHAR2(4)
 EMPNAME                                                        VARCHAR2(32)

select length(deptno) from scott.dept where empname='xiaoming';

LENGTH(DEPTNO)
--------------
             4

SQL> alter table scott.dept modify deptno char(8);
SQL> desc scott.dept 
  Name                                                  Null?    Type
 ----------------------------------------------------- -------- ------------------------------------
 DEPTNO                                                         CHAR(8)
 EMPNAME                                                        VARCHAR2(32)
SQL> select length(deptno) from scott.dept where empname='xiaoming';

LENGTH(DEPTNO)
--------------
             8

被填充了空格,字段值是否与原来不一样了呢?
试一下同一字符串末尾带空格与不带空格进行比较

SQL> select 1 from dual where '010'='010  ';
         1
----------
         1

可以发现,Oracle认为同一字符串的末尾带空格与不带空格是相等的;

4、给字段新增默认值

给字段新增默认值时,需要明确的是,表中该字段已经存在的字段值不会发生改变,原有的NULL值也不会被默认值所填充。

SQL> insert into scott.emp values ('87654321',null);
SQL> select * from scott.emp;

     EMPNO EMPNAME
---------- --------------------------------
  12345678 xiaoming
  87654321

SQL> alter table scott.emp modify empname default 'xiaoming';
SQL> @col_detail
Enter value for owner: SCOTT
Enter value for tabname: EMP
Enter value for colname: EMPNAME

Table                          Column                                                                               Null
Name                           Name                           DATA_TYPE                      DATA_LENGTH DATA_DEFAU able
------------------------------ ------------------------------ ------------------------------ ----------- ---------- ----
EMP                            EMPNAME                        VARCHAR2                                32 'xiaoming' Y

SQL> select * from scott.emp;

     EMPNO EMPNAME
---------- --------------------------------
  12345678 xiaoming
  87654321

SQL> insert into scott.emp values('',default);
SQL> select * from scott.emp;
     EMPNO EMPNAME
---------- --------------------------------
  12345678 xiaoming
  87654321
           xiaoming

#SQL脚本 col_detail.sql
select table_name,column_name,data_type,data_length,data_default,nullable 
  from dba_tab_columns
 where owner = upper('&owner') 
   and table_name = upper('&tabname') 
   and column_name=upper('&colname');
最后修改时间:2024-05-28 10:38:07
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

文章被以下合辑收录

评论