Исключение при вставке таблицы Oracle DB со столбцом Clob в Groovy

Я пытаюсь вставить файл в таблицу Oracle db с помощью groovy. Я использую следующий код:

import groovy.io.FileType
import groovy.sql.Sql
import oracle.jdbc.OracleDriver

import java.sql.Date

final def PROJECT_DIR = "/appdata/project/pmp"
final def SCRIPT_DIR = "/scm/src/main/scripts"

// To be able to use driver...
new OracleDriver();

sql = Sql.newInstance("jdbc:oracle:thin:@localhost:1521:XE", "PMP", "pmp")

sql.execute("delete from SCM_GROOVY_SCRIPTS")

def dir = new File(PROJECT_DIR + SCRIPT_DIR);
dir.eachFileRecurse(FileType.FILES) { file ->
    String scriptName = file.name.substring(0, file.name.indexOf('.'))
    def timestamp = new Date(System.currentTimeMillis())

    println scriptName
    println timestamp

    List<Object> params = new ArrayList<>()
    params.add(scriptName)
    params.add(file.bytes)
    params.add(timestamp)

    sql.execute("INSERT INTO SCM_GROOVY_SCRIPTS (SCRIPT_NAME, SCRIPT_SOURCE, LAST_UPDATED) VALUES (?, ?, ?)", params)
}

sql.close()

При выполнении кода я получаю следующие выходные данные.

ServiceUpdateRule

2016-12-28

28 декабря 2016 11:01: 56язык SQL.Sql execute
Предупреждение: не удалось выполнить: вставка в SCM_GROOVY_SCRIPTS
(SCRIPT_NAME, SCRIPT_SOURCE, LAST_UPDATED) ЗНАЧЕНИЯ (?, ?, ?) потому что:
ORA-01461: можно привязать длинное значение только для вставки в длинный столбец

Поймали: java.язык SQL.SQLException: ORA-01461: можно привязать только длинное значение
для вставки в длинную колонку

Ява.язык SQL.SQLException: ORA-01461: можно привязать длинное значение только для
вставить в длинную колонку

    at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:113)
    at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:331)
    at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:288)
    at oracle.jdbc.driver.T4C8Oall.receive(T4C8Oall.java:754)
    at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:219)
    at oracle.jdbc.driver.T4CPreparedStatement.executeForRows(T4CPreparedStatement.java:972)
    at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1192)
    at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3415)
    at oracle.jdbc.driver.OraclePreparedStatement.execute(OraclePreparedStatement.java:3521)
    at InsertUpdate$_run_closure1.doCall(InsertUpdate.groovy:35)
    at InsertUpdate.run(InsertUpdate.groovy:23)

Если я передаю аргумент clob как null вместо file.байт, он вставляет все строки без каких-либо ошибок. Структура моей таблицы следующая:

CREATE TABLE SCM_GROOVY_SCRIPTS (
        SCRIPT_NAME VARCHAR2(255) NOT NULL,
        SCRIPT_SOURCE CLOB,
        LAST_UPDATED DATE DEFAULT SYSDATE ,
        PRIMARY KEY (SCRIPT_NAME)
);

Кроме того, код работает, если я использую тип данных BLOB вместо CLOB.

1 ответ

  1. Наконец, я нашел способ вставить тип данных CLOB.

    Решение заключается в использовании java.язык SQL.Clob и oracle.язык SQL.CLOB классы.

    import groovy.io.FileType
    import groovy.sql.Sql
    import oracle.jdbc.OracleDriver
    import oracle.sql.CLOB
    
    import java.sql.Clob
    import java.sql.Date
    
    final def PROJECT_DIR = "/appdata/project/pmp"
    final def SCRIPT_DIR = "/scm/src/main/scripts"
    
    // To be able to use driver...
    new OracleDriver();
    
    Sql sql = Sql.newInstance("jdbc:oracle:thin:@localhost:1521:XE", "PMP", "pmp")
    
    sql.execute("delete from SCM_GROOVY_SCRIPTS")
    
    def dir = new File(PROJECT_DIR + SCRIPT_DIR);
    dir.eachFileRecurse(FileType.FILES) { file ->
        String scriptName = file.name.substring(0, file.name.indexOf('.'))
        def timestamp = new Date(System.currentTimeMillis())
    
        println scriptName
        println timestamp
    
        Clob clob = CLOB.createTemporary(sql.getConnection(), false, CLOB.DURATION_SESSION);
        clob.setString(1, file.getText("UTF-8"))
    
        List<Object> params = new ArrayList<>()
        params.add(scriptName)
        params.add(clob)
        params.add(timestamp)
    
        sql.execute("INSERT INTO SCM_GROOVY_SCRIPTS (SCRIPT_NAME, SCRIPT_SOURCE, LAST_UPDATED) VALUES (?, ?, ?)", params)
    }
    
    sql.close()