oracle 数据库 lob 字段之 clob 存储

os: centos 7.4
db: oracle 11.2.0.4

版本

# cat /etc/centos-release
CentOS Linux release 7.4.1708 (Core) 
# 
# su - oracle
Last login: Tue Jan 21 03:40:05 CST 2020 on pts/0
$ sqlplus / as sysdba;

SQL*Plus: Release 11.2.0.4.0 Production on Mon Feb 3 10:29:09 2020

Copyright (c) 1982, 2013, Oracle.  All rights reserved.


Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
With the Partitioning, Real Application Clusters, Automatic Storage Management, OLAP,
Data Mining and Real Application Testing options

SQL> set lines 300;
SQL> set pages 300;
SQL> 
SQL> select * from v$version;

BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
PL/SQL Release 11.2.0.4.0 - Production
CORE	11.2.0.4.0	Production
TNS for Linux: Version 11.2.0.4.0 - Production
NLSRTL Version 11.2.0.4.0 - Production

SQL> 

create table

SQL> set lines 300;
set pages 300;

SQL> 
SQL> create table tmp_t0(
  id   integer,
  name varchar2(100),
  memo clob
)
;

SQL> SELECT TO_CHAR(DBMS_METADATA.GET_DDL('TABLE','TMP_T0','SCOTT2')) FROM DUAL;

TO_CHAR(DBMS_METADATA.GET_DDL('TABLE','TMP_T0','SCOTT2'))
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

  CREATE TABLE "SCOTT2"."TMP_T0"
   (	"ID" NUMBER(*,0),
	"NAME" VARCHAR2(100),
	"MEMO" CLOB
   ) SEGMENT CREATION DEFERRED
  PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255
 NOCOMPRESS LOGGING
  TABLESPACE "USERS"
 LOB ("MEMO") STORE AS BASICFILE (
  TABLESPACE "USERS" ENABLE STORAGE IN ROW CHUNK 8192 RETENTION
  NOCACHE LOGGING )

请注意最后面对 MEMO 列的描述,默认行为是启用行内存储(ENABLE STORAGEIN IN ROW)
LOB (“MEMO”) STORE AS BASICFILE (
TABLESPACE “USERS” ENABLE STORAGE IN ROW CHUNK 8192 RETENTION
NOCACHE LOGGING )

SQL> col table_name format a30;
col column_name format a30;
col SEGMENT_NAME format a60;

SQL> select ul.TABLE_NAME,ul.COLUMN_NAME,ul.SEGMENT_NAME,ul.TABLESPACE_NAME,
       ul.retention,ul.CACHE,ul.IN_ROW,ul.SECUREFILE,ul.chunk,ul.LOGGING
       --ul.*
from user_lobs ul
where 1=1
;

TABLE_NAME		       COLUMN_NAME		      SEGMENT_NAME						   TABLESPACE_NAME		   RETENTION CACHE	IN_ SEC      CHUNK LOGGING
------------------------------ ------------------------------ ------------------------------------------------------------ ------------------------------ ---------- ---------- --- --- ---------- -------
TMP_T0			       MEMO			      SYS_LOB0000479841C00003$$ 				   USERS			    900 NO 	YES NO	      8192 YES


SQL> select *
from user_segments us
where 1=1
and us.segment_name in (
 'TMP_T0',
 'SYS_LOB0000479841C00003$$'
);

no rows selected

insert into

在网上搜索 lob 字段设置 ENABLE STORAGE IN ROW 后,在写入字节大于4000(字符大于 1982)时,会单独分配 lob 存储空间。
1982*2+36=4000

SQL> declare 
  lv_name varchar2(30000);
begin
  for c_f in (
    select level as id,
           '我' as name
      from dual
     connect by level <=1982
  )
  loop
     lv_name:=lv_name||c_f.name;
     insert into TMP_T0
     select c_f.id,c_f.name,lv_name from dual
     ;
     commit;
  end loop;

end;
/

ERROR at line 1:
ORA-01461: can bind a LONG value only for insert into a LONG column
ORA-06512: at line 12

看报错信息是 lv_name 在拼接到一定长度字符串时转换成了 LONG 类型,然后插入 CLOB 字段

这个报错可能有以下几种原因:
1、插入到字符串长度大于4000字节。
2、插入到表中的记录的某个字段数据的实际长度大于2000个字节(如果是UTF-8,则是1333个字节);或者是插入的记录中有两个或两个以上长度大于2000字节的字符串。

把 lv_name 换成 clob 试下,执行成功。

SQL> declare 
  lv_name clob;
begin
  for c_f in (
    select level as id,
           '我' as name
      from dual
     connect by level <=1982
  )
  loop
     lv_name:=lv_name||c_f.name;
     insert into TMP_T0
     select c_f.id,c_f.name,lv_name from dual
     ;
     commit;
  end loop;

end;
/

参考:
http://download.oracle.com/docs/cd/E11882_01/appdev.112/e18294/adlob_tables.htm#ADLOB45267

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

数据库人生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值