Hi,
I didn't originally write this code so I wouldn't know much about it. Basically I have an option in IR for each row to open a modal dialog window where you can add comment to the row. Someone bult Add Comments button in a column with JS, I think.
When modal dialog is open, besides the textbox for posting comment, there is APEX File Browse.. item, and below it an UPLOAD button (finally there's Save button to complete actions which closes modal dialog). When I browse one single file, and click UPLOAD, it gets uploaded, but when I try to upload another file after that (so to have multiple files), there is a JS error message saying 'Internal Server Error'.
The File browse item is for column ATTACHMENT, its in the context of fetching for a specific table, XXEXT_AP_HOLDS_COMMENTS. In that table ATTACHMENT column is defined as BLOB.
The relevant settings for this item are:
MIME Type Column: FILE_MIME_TYPE
Filename Column: FILENAME
Display Download Link: Yes
Content Disposition: Attachment
Custom Attributes: Multiple
Type: Database Column
Database column: ATTACHMENT
Then for UPLOAD button there is Dynamic Action:
Event: Click
Condition: fileInputElem.files.length != 0
Execute JS code:
spinner = new Spinner(spinOptions).spin(spinTargetElem);
fileIndex = 0;
uploadFile(fileIndex);
Event: Upload file(s) and Refresh
On page processing there are:
After Submit process - Save Attachments:
declare
lco_collection_name constant apex_collections.collection_name%type := 'UPLOADED_FILES';
begin
for i in (select c001 filename, c002 mime_type, blob001 attachment
from apex_collections
where collection_name = 'UPLOADED_FILES')
loop
insert into xxext_aphold_attachments ( object_type, object_id, attachment, attachment_name, attachment_mime ) values
( 'APHOLDS_COMMENT', :P11_HOLD_COMMENT_ID, i.attachment, i.filename, i.mime_type );
end loop;
if apex_collection.collection_exists(lco_collection_name) then
apex_collection.truncate_collection(
p_collection_name => lco_collection_name
);
end if;
end;
Ajax Callback - UPLOAD_FILE:
declare
lco_collection_name constant apex_collections.collection_name%type := 'UPLOADED_FILES';
l_blob blob;
l_filename varchar2(200);
l_mime_type varchar2(200);
l_token varchar2(32000);
begin
l_filename := apex_application.g_x01;
l_mime_type := nvl(apex_application.g_x02, 'application/octet-stream');
-- build BLOB from f01 30k array (base64 encoded)
dbms_lob.createtemporary(l_blob, false, dbms_lob.session);
for i in 1 .. apex_application.g_f01.count loop
l_token := wwv_flow.g_f01(i);
if length(l_token) > 0 then
dbms_lob.append(
dest_lob => l_blob,
src_lob => to_blob(utl_encode.base64_decode(utl_raw.cast_to_raw(l_token)))
);
end if;
end loop;
-- add collection member (only if BLOB is not null)
if dbms_lob.getlength(l_blob) is not null then
apex_collection.add_member(
p_collection_name => lco_collection_name,
p_c001 => l_filename,
p_c002 => l_mime_type,
p_blob001 => l_blob
);
end if;
apex_json.open_object;
apex_json.write(
p_name => 'result',
p_value => 'success'
);
apex_json.close_object;
exception
when others then
apex_json.open_object;
apex_json.write(
p_name => 'result',
p_value => 'fail'
);
apex_json.close_object;
end;
Ajax Callback - DELETE FILE:
begin
apex_collection.delete_member(
p_collection_name => 'UPLOADED_FILES',
p_seq => apex_application.g_x01
);
apex_json.open_object;
apex_json.write(
p_name => 'result',
p_value => 'success'
);
apex_json.close_object;
exception
when others then
apex_json.open_object;
apex_json.write(
p_name => 'result',
p_value => 'fail'
);
apex_json.close_object;
end;
AFTER HEADER process - Initialize UPLOADED_FILES collection:
declare
lco_collection_name constant apex_collections.collection_name%type := 'UPLOADED_FILES';
begin
if apex_collection.collection_exists(lco_collection_name) then
apex_collection.truncate_collection(
p_collection_name => lco_collection_name
);
else
apex_collection.create_collection(
p_collection_name => lco_collection_name
);
end if;
end;
I hope this is enough details. I don't know if I would be able to reproduce this on apex.com, in the same context, and also the APEX version here is 5.0.1.
As said, I didn't build this feature from scratch so I have to read into someone's code, and I hope you can help me clarify it, for the purpose of attaching multiple files (ie adding one after another) - where I stumble upon error 'Internal Server Error' when doing so.
Is there a visible problem with the approach, or could it be related to webserver settings, BLOB table column, or something similar?
Thanks.