赵延东的一亩三分地

赵延东的一亩三分地

系列文章目录



前言

本篇文章主要给讲解的Oracle12C+的新特性是:在Oracle12C之前,VARCHAR2/NVARCHAR2类型得最大长度是4000字节,而raw类型是2000字节。12c我们可以将这几种类型的最大长度扩展到32767字节,从而大大减少对CLOB等大字段的使用频率。本文章会教大家如何在CDB+PDB环境启用扩展,以及如何使用和使用过程中的注意事项(比如:ORA-24920:列大小对于客户机过大)

【SQL开发实战技巧】这一系列博主当作复习旧知识来进行写作,毕竟SQL开发在数据分析场景非常重要且基础,面试也会经常问SQL开发和调优经验,相信当我写完这一系列文章,也能再有所收获,未来面对SQL面试也能游刃有余~。


Oracle12C常用新特性☞VARCHAR2/NVARCHAR2类型最大长度由4000字节扩展到32767字节

在12c之前,VARCHAR2/NVARCHAR2类型得最大长度是4000字节,而raw类型是2000字节。12c我们可以将这几种类型的最大长度扩展到32767字节,从而大大减少对CLOB等大字段的使用频率。

案例一:CDB+PDB环境启用扩展

当前操作的是CDB环境:

SQL> show con_name
CON_NAME
-------------------
CDB$ROOT

启动数据库到upgrade模式:

SQL>  shutdown immediate;
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> startup upgrade;
ORACLE instance started.

Total System Global Area  830472192 bytes
Fixed Size		    8798216 bytes
Variable Size		  633343992 bytes
Database Buffers	  184549376 bytes
Redo Buffers		    3780608 bytes
Database mounted.
Database opened.
SQL>  alter system  set max_string_size=extended scope=spfile;
SQL> @$ORACLE_HOME/rdbms/admin/utl32k.sql
。。。。省略输出

检查一下有没有产生失效对象:

SQL> select count(*) from dba_objects where status<>'VALID';
  COUNT(*)
----------
	 0

没有失效对象,关闭数据库,将数据库以读写模式打开:

SQL>  shutdown immediate;
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> startup
ORACLE instance started.

Total System Global Area  830472192 bytes
Fixed Size		    8798216 bytes
Variable Size		  633343992 bytes
Database Buffers	  184549376 bytes
Redo Buffers		    3780608 bytes
Database mounted.
Database opened.

当前操作对象为CDB

SQL> show con_name
CON_NAME
------------------------------
CDB$ROOT

查看当前存在PDB状态:

SQL>  show pdbs

    CON_ID CON_NAME			  OPEN MODE  RESTRICTED
---------- ------------------------------ ---------- ----------
	 2 PDB$SEED			  MOUNTED
	 3 PDB1 			  MOUNTED

指定当前操作对象为PDB1:

SQL> alter session set container=pdb1;
Session altered.

将PDB1重新启动到migrate模式:

SQL> ALTER PLUGGABLE DATABASE OPEN UPGRADE;
Pluggable database altered.
SQL>  show pdbs

    CON_ID CON_NAME			  OPEN MODE  RESTRICTED
---------- ------------------------------ ---------- ----------
	 3 PDB1 			  MIGRATE    YES

执行扩展脚本:

SQL> @$ORACLE_HOME/rdbms/admin/utl32k.sql

再次检查是否有失效对象,发现没有,继续将PDB1关闭,再次以READ WRITE模式打开:

SQL> ALTER PLUGGABLE DATABASE close;
Pluggable database altered.
SQL> ALTER PLUGGABLE DATABASE OPEN READ WRITE ;
Pluggable database altered.
SQL>  show pdbs
    CON_ID CON_NAME			  OPEN MODE  RESTRICTED
---------- ------------------------------ ---------- ----------
	 3 PDB1 			  READ WRITE NO

再次回到CDB查看当前存在的PDB状态:

SQL>  show pdbs
    CON_ID CON_NAME			  OPEN MODE  RESTRICTED
---------- ------------------------------ ---------- ----------
	 2 PDB$SEED			  MOUNTED
	 3 PDB1 			  READ WRITE NO

接下来继续对PDB$SEED做上面操作:

SQL> alter session set container=PDB$SEED;
Session altered.
SQL> ALTER PLUGGABLE DATABASE OPEN UPGRADE;
Pluggable database altered.
SQL> @$ORACLE_HOME/rdbms/admin/utl32k.sql
。。。。。省略输出

再次检查没有失效对象后,重启PDB$SEED到read only状态:

SQL>  ALTER PLUGGABLE DATABASE close;
Pluggable database altered.
SQL>  ALTER PLUGGABLE DATABASE OPEN READ ONLY;
Pluggable database altered.
SQL> show pdbs
    CON_ID CON_NAME			  OPEN MODE  RESTRICTED
---------- ------------------------------ ---------- ----------
	 2 PDB$SEED			  READ ONLY  NO

案例二:扩展数据类型使用

在将max_string_size设置为extended后,就在也恢复不了默认的standard了,如果想回去,就得做一个不完全恢复将这个数据库恢复到这个变更得时间点之前状态,或则预先启用flashback database等。
在激活扩展类型后,下面这样创建表就能通过:

Create table t(id number,test varchar2(32767));

其实扩展数据类型得内部是通过lob来实现得,可以通过下面测试来看到:

select object_name,object_type from user_objects;

【SQL开发实战技巧】系列(四十五):Oracle12C常用新特性☞VARCHAR2/NVARCHAR2类型最大长度由4000字节扩展到32767字节-LMLPHP

还可以通过user_lobs来进一步确认lob段得详情:

select table_name, column_name, segment_name, tablespace_name, in_row
  from user_lobs
 where table_name = 'T';

【SQL开发实战技巧】系列(四十五):Oracle12C常用新特性☞VARCHAR2/NVARCHAR2类型最大长度由4000字节扩展到32767字节-LMLPHP

初始化数据(第二条数据test列长度为8000):

insert into t values(1,'a');
insert into t
  select 2,
         dbms_random.string('u', '4000') || dbms_random.string('u', '4000')
    from dual;

做查询:

select * from t;

此查询在sqlplus查询,可以正常出来数据不报错,但是在plsql中报错如下:
【SQL开发实战技巧】系列(四十五):Oracle12C常用新特性☞VARCHAR2/NVARCHAR2类型最大长度由4000字节扩展到32767字节-LMLPHP

本机的PLSQL软件版本为12,报此错误可能是由于本机用windows装的Oracle11G软件连接的原因,可以在plsql通过to_clob函数或则substr方式来显示:

select t.id,to_clob(t.test)test from t;

【SQL开发实战技巧】系列(四十五):Oracle12C常用新特性☞VARCHAR2/NVARCHAR2类型最大长度由4000字节扩展到32767字节-LMLPHP

当然,将本机windows下的Oracle11g软件升级到12c就不会报错了:
升级到12C后,再次查看表:
【SQL开发实战技巧】系列(四十五):Oracle12C常用新特性☞VARCHAR2/NVARCHAR2类型最大长度由4000字节扩展到32767字节-LMLPHP

可以正常查看了,而且的确是8000个字符,并没有截断。所以可以确定,上面plsql报错是由于Oracle客户端版本问题。
为表新增一列:

alter table t add tes varchar2(4000);

再次插入数据:

insert into t
  select 3,'b',
         dbms_random.string('u', '4000')
from dual;

再次查询用户对象:
【SQL开发实战技巧】系列(四十五):Oracle12C常用新特性☞VARCHAR2/NVARCHAR2类型最大长度由4000字节扩展到32767字节-LMLPHP

为表再次新加一列:

alter table t add t4001 varchar2(4001);

查询表对应的lob段详情:

select table_name, column_name, segment_name, tablespace_name, in_row
  from user_lobs
 where table_name = 'T';

【SQL开发实战技巧】系列(四十五):Oracle12C常用新特性☞VARCHAR2/NVARCHAR2类型最大长度由4000字节扩展到32767字节-LMLPHP

发现新家tes列时,lob段并没新增,但是再次新加列t4001时,lob段多了一个,也就是说,在启用了列扩展后,只有当定义列长度超过4000时,才会在内部以拓展列的方式存储数据。


总结

本篇文章主要给讲解的Oracle12C+的新特性是:在Oracle12C之前,VARCHAR2/NVARCHAR2类型得最大长度是4000字节,而raw类型是2000字节。12c我们可以将这几种类型的最大长度扩展到32767字节,从而大大减少对CLOB等大字段的使用频率。本文章会教大家如何在CDB+PDB环境启用扩展,以及如何使用和使用过程中的注意事项(比如:ORA-24920:列大小对于客户机过大)

04-08 14:35