首页 > 数据库 > Oracle > lob字段类型转换ora-22858
程序中出现错误,缘于是因为blob字段缺省值为null,需要修改blob字段的缺省值为empty_blob()
SQL> desc t_lob001;
Name
Null? Type
-----------------------------------------
-------- ----------------------------
ID NUMBER
CONTENT
BLOB
SQL> alter table t_lob001 modify(content blob default
empty_blob());
alter table t_lob001 modify(content blob default
empty_blob())
*
ERROR at line 1:
ORA-22858: invalid alteration of datatype
上述sql语句由于进行了blob到blob的转换,出现了无效的数据类型ora-22858
同样非lob类型转换为lob类型同样也不允许。
SQL> alter table t_lob001 add name varchar2(1000);
Table altered.
SQL> alter table t_lob001 modify(name blob default
empty_blob());
alter table t_lob001 modify(name blob default empty_blob())
*
ERROR at line 1:
ORA-22858: invalid alteration of datatypeSQL> desc
t_lob001;
Name
Null? Type
-----------------------------------------
-------- ----------------------------
ID
NUMBER
CONTENT
BLOB
由于修改默认值,可以直接采取alter
table t_lob001 modify( content default empty_blob())就可以了。
分析一下这个错误的产生,将lob字段转换为别的数据类型,或者将别的数据类型转换为lob类型时,oracle是不允许的。
[oracle@server127 ~]$ oerr ora 22858
22858, 00000, "invalid alteration of
datatype"
// *Cause: An
attempt was made to modify the column type to object, REF,
//
nested table, VARRAY or LOB type.
// *Action:
Create a new column of the desired type and copy the current
//
column data to the new type using the appropriate type
//
constructor.
如果需要进行转换,可以参照在线重定义来进行转换字段类型。
接下来分析下lob的缺省值null和empty_blob()的区别,null值由于是未知, oracle不会为其分配存储空间,
而empty_blob()仅仅表示该lob字段为空值,oracle还是会为其分配lob字段段头的一些存储单位。
SQL> alter
table t_lob001 modify(content default empty_blob());
Table altered.
SQL> alter table t_lob001 add(article blob default
null);
Table altered.
SQL> desc t_lob001;
Name
Null? Type
-----------------------------------------
-------- ----------------------------
ID NUMBER
CONTENT
BLOB
NAME
VARCHAR2(1000)
ARTICLE
BLOB
SQL> insert into t_lob001(id,name)
values(1,'xiaoyu');
1 row created.
SQL> commit;
Commit complete.
SQL> select dbms_lob.getlength(content)
content_length,dbms_lob.getlength(article) article_length from t_lob001;
CONTENT_LENGTH ARTICLE_LENGTH
-------------- --------------
0
下面的测试更能说明empty_blob()仅仅只是一个空的lob字段,并不是null未知,而且会为其分配相应的lob字段段头的存储位置。
SQL> select id from t_lob001 where content is null;
no rows selected
SQL> select id from t_lob001 where article is null;
ID
----------
1
关于存储空间null和empty_blob()测试:
SQL> declare
2 begin
3 for i in 1..1000 loop
4 insert into t_lob001
values(1,null,'xiaoyu',null);
5 end loop;
6 commit;
7 end;
8 /
PL/SQL procedure successfully completed.
SQL> analyze table t_lob001 compute statistics;
Table analyzed.
SQL> select blocks from user_tables where
table_name='T_LOB001';
BLOCKS
----------
5
SQL> truncate table t_lob001;
Table truncated.
SQL> declare
2 begin
3 for i in 1..1000 loop
4 insert into t_lob001
values(1,empty_blob(),'xiaoyu',null);
5 end loop;
6 commit;
7 end;
8 /
PL/SQL procedure successfully completed.
SQL> analyze table t_lob001 compute statistics;
Table analyzed.
SQL> select blocks from user_tables where
table_name='T_LOB001';
BLOCKS
----------
13
可以看出empty_blob()存储空间占用了较多的存储空间。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/25362835/viewspace-1059194/ ,如需转载,请注明出处,否则将追究法律责任。