Oracle clob怎么存储超过4000长度的数据,你了解吗

目录

方式一、使用存储过程:

方式二、使用to_clob函数

方式三、mybatis中的方法

附: oracle将把varchar2字段(长度4000)改为clob类型

参考资料:


题记:我们知道Oracle存储的字段长度是有限制,常见的varchar2的保存长度最大为4000,对一些业务字段值可能超过4000的情况,可以使用clob类型进行存储,但是如果直接将大字符串保存到clob的列中,会提示错误:ORA-01704 字符串超长。

原理如下:当直接将clob数据插入的时候,Oracle其实还是将clob类型当为varchar类型往数据库插入,而clob的字段长度本身默认最大长度就是4000,很尴尬,又会出现问题。

如下图:新创建表clob类型不设或者给大于4000的值,当保存时会自动调整为4000。

Oracle clob怎么存储超过4000长度的数据,你了解吗_第1张图片

先看下说明:“CLOB全称为字符大型对象(Character Large Object)。它与LONG数据类型类似,只不过CLOB用于存储数据库中的大型单字节字符数据块,不支持宽度不等的字符集。可存储的最大大小为4G字节。”


那么问题来了,我们知道clob可以保存很大的数据,究竟如何来进行保存呢,笔者查阅相关资料,这里提供两种方法:

先建表:

-- ----------------------------
-- Table structure for CLOBTEST
-- ----------------------------
DROP TABLE "CLOBTEST";
CREATE TABLE "CLOBTEST" (
  "ID" NUMBER NOT NULL ,
  "MSG" CLOB 
)
TABLESPACE "USERS"
LOGGING
NOCOMPRESS
PCTFREE 10
INITRANS 1
STORAGE (
  INITIAL 65536 
  NEXT 1048576 
  MINEXTENTS 1
  MAXEXTENTS 2147483645
  BUFFER_POOL DEFAULT
)
PARALLEL 1
NOCACHE
DISABLE ROW MOVEMENT
;

方式一、使用存储过程:

句式:

declare 
  v_clob clob :='>4000很长的一段文字'; 
begin 
  insert into tablename values(1,v_clob); 
end; 

案例代码如下:

package sql;

import java.sql.*;

/**
 * @author xasnow
 * @Date 2020/5/12
 */
public class ClobDemo2 {

    public static void main(String[] args) {
        Connection conn = null;
        Statement stmt = null;
        ResultSet rs = null;
        try {
            Class.forName("oracle.jdbc.driver.OracleDriver"); //注册数据库驱动
            try {
                String url = "jdbc:oracle:thin:@localhost:1521:orcl";//orcl要改为数据库名称
                String username = "username"; //要改填数据库用户名
                String password = "password"; //要改填数据库密码
                conn= DriverManager.getConnection(url,username,password); //建立连接
                stmt = conn.createStatement();
                // 执行SQL语句
                rs = getResultSet(stmt, rs);
                rs.close();
                stmt.close();
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    private static ResultSet getResultSet(Statement stmt, ResultSet rs) throws SQLException {
        for (int i = 0; i < 10 ; i++) {
            System.out.println(i);
            rs = stmt.executeQuery("declare v_clob clob :='124aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1230000000000000000000000000000000000000000000000大风起兮云飞扬"+ i +"'; begin insert into CLOBTEST values("+ i +",v_clob); end; ");
        }
        return rs;
    }

}

图1:执行后结果,可以看到超长的字符已经插入进来。

Oracle clob怎么存储超过4000长度的数据,你了解吗_第2张图片

图2:单看其中的一条数据,是非常长的。

Oracle clob怎么存储超过4000长度的数据,你了解吗_第3张图片

 

方式二、使用to_clob函数

  • split the long character string into 4000 character or less chunks
  • create clobs for each chunk using to_clob() function
  • concatenate the clobs

Here is an example:

insert into  (clob_column)
  values
  (
      to_clob(' <=4000 symbols ')
    ||to_clob(' <=4000 symbols ')
    ||to_clob(' <=4000 symbols ')
    ...
    ||to_clob(' <=4000 symbols ')
  );

示例代码:

package sql;

import java.sql.*;

/**
 * @author xasnow
 * @Date 2020/5/12
 */
public class ClobDemo3 {

    public static void main(String[] args) {
        Connection conn = null;
        Statement stmt = null;
        ResultSet rs = null;
        try {
            Class.forName("oracle.jdbc.driver.OracleDriver"); //注册数据库驱动
            try {
                String url = "jdbc:oracle:thin:@localhost:1521:orcl";//orcl要改为数据库名称
                String username = "username"; //要改填数据库用户名
                String password = "password"; //要改填数据库密码
                conn= DriverManager.getConnection(url,username,password); //建立连接
                stmt = conn.createStatement();
                // 执行SQL语句
                rs = stmt.executeQuery("insert into CLOBTEST values(112,to_clob(' <=4000 symbols aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')||to_clob(' 

图三:数据进行拼接已完全插入数据库种。

Oracle clob怎么存储超过4000长度的数据,你了解吗_第4张图片

 

参考:将长报文转为to_clob函数拼接的参考方法:

	/**
	 * 将超长的报文内容转为clob可以保存的句式
	 * @param msgItemLength  每次截取的长度
	 * @param msg  原始长报文
	 */
    private static String convertClobMsg(int msgItemLength, String msg) {
        int i = msg.length() / msgItemLength;
        StringBuilder sb = new StringBuilder(); //不能给初始值,报文可能超长未知。
        for (int j = 0; j < 1 + i; j++) {
            int starSize = j * msgItemLength;
            int endSize = (j + 1) * msgItemLength;
            if (endSize <= msg.length()) { //  前面的分批截取
                String substring = msg.substring(starSize, endSize);
                sb.append("to_clob('").append(substring).append("')||");
            } else if (starSize != msg.length()) { // 最后一个批次,本次截取至结尾,如果startSize与字符串长度相等,就不再截取
                String substring = msg.substring(starSize);
                sb.append("to_clob('").append(substring).append("')||");
            }
        }
        return sb.append("to_clob('')").toString();
    }

 

方式三、mybatis中的方法

解决方式:使用变量,通过PL/SQL将数据赋予CLOB变量,通过引用变量将数据插入,指导思想其实和存储过程的变量绑定是一致的。

mybatis具体XML内容如下:



  DECLARE
         V_LANG CLOB := #{text,jdbcType=CLOB};
  BEGIN

    INSERT INTO test(ID, TEXT) VALUES(#{id,jdbcType=VARCHAR}, V_LANG);

  END;

附: oracle将把varchar2字段(长度4000)改为clob类型

--增加大字段项
alter table tableName add hehe clob;
--将需要改成大字段的项内容copy到大字段中
update tableName set hehe=ASSetsinvestment;
--删除原有字段
alter table tableName drop column ASSetsinvestment;
--将大字段名改成原字段名
alter table tableName rename column hehe to ASSetsinvestment;

参考资料:

1.  方式2 https://stackoverflow.com/questions/18394691/oracle-clob-cant-insert-beyond-4000-character

2. 方式3  https://www.cnblogs.com/call-me-pengye/p/11136870.html

 

你可能感兴趣的:(功能代码,数据库)