2

I am working on Java+Spring+Oracle application. I am trying to add a new function on the database that stores NClob in a custom type. I ran into the error

ORA-65502: cannot access temporary LOB data

but I am not sure how to fix my issue.

Please pardon me that I am still new to PL/SQL and it is my first time dealing with NClob.

To begin with, I have a table like this:

CREATE TABLE "NOTIFICATION" (
    "NOTIFICATION_ID" NUMBER GENERATED BY DEFAULT ON NULL AS IDENTITY,
    ...
    "NOTIFICATION_CONTENT" NCLOB,                -- HTML content of notification
    ...
    "COMMENTS"  NCLOB,
    ...
    CONSTRAINT "PK_NOTIFICATION_ID" PRIMARY KEY ("NOTIFICATION_ID")
);

I have a custom type to read/write encapsulated data:

create or replace TYPE NOTIFICATION_TYP FORCE AS OBJECT (
    "NOTIFICATION_ID" NUMBER,
    ...
    "NOTIFICATION_CONTENT" NCLOB,                -- HTML content of notification
    ...
    "COMMENTS"  NCLOB,
    ...
    constructor function NOTIFICATION_TYP return self as result
) NOT FINAL;

and its body simply as:

create or replace type body NOTIFICATION_TYP is
  constructor function NOTIFICATION_TYP return self as result is
  begin
    return;
  end;
end;

So basically my (simplified)function in the database package is like this:

function create_notification(
         pi_notification       in        NOTIFICATION_TYP
        ,po_notification_id    out       number
        ,po_return             out       return_typ
    )
    return integer as
        v_excep_msg varchar2(200);
    begin
        insert into NOTIFICATION (
            ...
            NOTIFICATION_CONTENT,
            ...
            COMMENTS,
            ...
        ) values (
            ...
            pi_notification.NOTIFICATION_CONTENT,
            ...
            pi_notification.COMMENTS,
            ...
        ) RETURNING NOTIFICATION_ID INTO po_notification_id;
        po_return := utils_pkg.get_success_info;
        return c_success;

    exception
        when OTHERS then
            v_excep_msg  :=  sqlerrm;
            po_return := utils_pkg.get_error_info(SQLCODE, SQLERRM);
            log_error_msg(
                 pi_app_name         =>  c_application_name
                ,pi_error_msg        =>  'Exception in creating notification'
                ,pi_error_details    =>  sqlerrm
            );

    return c_failure;
end create_notification;

So from Java end, I am using StoredProcedure and SQLData to call the function in the package. CreateNotificationFunction.java:

import ...
public class CreateNotificationFunction  extends StoredProcedure{

    public CreateNotificationFunction(JdbcTemplate jdbcTemplate){
         super(jdbcTemplate, DAOConstants.CREATE_NOTIFICATION_FUNCTION);
         setFunction(true);
         declareParameter(new SqlOutParameter(DAOConstants.PO_FUNCTION_RESULT, OracleTypes.VARCHAR));
         declareParameter(new SqlParameter(DAOConstants.PI_NOTIFICATION,OracleTypes.STRUCT,DAOConstants.TYPE_NOTIFICATION));
         declareParameter(new SqlOutParameter(DAOConstants.PO_NOTIFICATION_ID, OracleTypes.NUMBER));
         declareParameter(new SqlOutParameter(DAOConstants.PO_RETURN,OracleTypes.STRUCT,DAOConstants.TYPE_RETURN,  
                new SqlReturnSqlData(SQLDBResult.class)));
         allowsUnusedParameters();
         compile();         
    }
    
    @SuppressWarnings({ "rawtypes" })
    public Map execute(JdbcTemplate jdbcTemplate, SQLNotification sqlNotification) {
      Map<String, Object> params = new HashMap<String, Object>();
        params.put(DAOConstants.PI_NOTIFICATION, sqlNotification);
        return super.execute(params);
    }   
}

SQLNotification.java:

public class SQLNotification implements SQLData {
    private String notificationContent;
    private String comments;
    private static Connection connection;
    ...

    @Override
    public void writeSQL(SQLOutput sqlOutput) throws SQLException {
        ...
        NClob notificationContentNClob = connection.createNClob();
        notificationContentNClob.setString(1, getNotificationContent());
        sqlOutput.writeNClob(notificationContentNClob);
        ...
        NClob commentsNClob = connection.createNClob();
        commentsNClob.setString(1, getComments());
        sqlOutput.writeNClob(commentsNClob);
        ...
    }
}

(Is this the correct way to insert Java String into Oracle's NClob?)

Not sure what went wrong...

I am unsure when this error occurs - Is it when creating the type instance? Is it when calling the function? Or, is it when inserting the data into the table?

user2526586
  • 972
  • 2
  • 12
  • 27

0 Answers0