Oracle APEX - Download selected files as zip - IR/IG checkbox selection - checkbox

I referred to this link create a download zip button to download files in zip format in Oracle apex latest version 22.2. It is working fine without any issues but only concern is; it downloads all the files in one zip file. Whereas my requirement is to include a checkbox on a report (either IG or IR) and to download selected files in one zip file.
Below is the table I am referring to. Its from Oracle apex sample files upload and download.
select
ID,
ROW_VERSION_NUMBER,
PROJECT_ID,
FILENAME,
FILE_MIMETYPE,
FILE_CHARSET,
FILE_BLOB,
FILE_COMMENTS,
TAGS,
CREATED,
CREATED_BY,
UPDATED,
UPDATED_BY
from EBA_DEMO_FILES
I tried searching over the internet and found few links pointing to APEX_ZIP, PL/SQL compress blob etc. But could not see any demo or working model similar to the link I provided above.
If anybody has working demo or blog,I request to share it. Many thanks.
Update: As suggested by Koen Lostrie, I am updating Page process code below:
DECLARE
l_id_arr apex_t_varchar2;
l_selected_id_arr apex_t_varchar2;
var_zip blob;
BEGIN
-- push all id values to an array
FOR i IN 1..APEX_APPLICATION.G_F03.COUNT LOOP
apex_string.push(l_id_arr,APEX_APPLICATION.G_F03(i));
FOR j IN 1 .. APEX_APPLICATION.G_F01.COUNT LOOP
IF APEX_APPLICATION.G_F01(j) = APEX_APPLICATION.G_F03(i) THEN
-- push all selected emp_id values to a 2nd array
apex_string.push(l_selected_id_arr,APEX_APPLICATION.G_F03(i));
END IF;
END LOOP;
END LOOP;
-- Create/clear the ZIP collection
APEX_COLLECTION.CREATE_OR_TRUNCATE_COLLECTION(
p_collection_name => 'ZIP');
-- Loop through all the files in the database
begin
for var_file in (select fi.filename, fi.file_blob, pr.project
from eba_demo_files fi
inner join eba_demo_file_projects pr on fi.project_id = pr.id
where fi.id in (SELECT column_value FROM table(apex_string.split(apex_string.join(l_selected_id_arr,':'),':'))))
loop
-- Add each file to the var_zip file
APEX_ZIP.ADD_FILE (
p_zipped_blob => var_zip,
p_file_name => var_file.project || '/' || var_file.filename,
p_content => var_file.file_blob );
end loop;
exception when no_data_found then
-- If there are no files in the database, handle error
raise_application_error(-20001, 'No Files found!');
end;
-- Finish creating the zip file (var_zip)
APEX_ZIP.FINISH(
p_zipped_blob => var_zip);
-- Add var_zip to the blob column of the ZIP collection
APEX_COLLECTION.ADD_MEMBER(
p_collection_name => 'ZIP',
p_blob001 => var_zip);
END;
Once page process is done, follow step 3 and 4 from the link provided in OP.
Below is the updated query:
select
ID,
ROW_VERSION_NUMBER,
PROJECT_ID,
FILENAME,
FILE_MIMETYPE,
FILE_CHARSET,
FILE_BLOB,
FILE_COMMENTS,
TAGS,
CREATED,
CREATED_BY,
UPDATED,
UPDATED_BY,
APEX_ITEM.CHECKBOX(1,ID) checkbox,
APEX_ITEM.TEXT(2,FILENAME) some_text,
APEX_ITEM.HIDDEN(3,ID) hidden_empno
from EBA_DEMO_FILES
Big Thanks to Koen Lostrie.
All credits goes to Koen Lostrie.
Thanks,
Richa

This is just an answer to the last comment - the base question was answered in the comments. The question in the comment is "how do I include APEX_ITEM.HIDDEN columns in my report without hiding the columns".
When the columns are hidden in the report, they're not rendered in the DOM, so the values do not exist when the form is posted. That is the reason you're getting the error.
However, take a step back and check what APEX_ITEM.HIDDEN generates. Add a column of type APEX_ITEM.HIDDEN to the report and inspect the column in the browser tools. It generates an input element of type "hidden", so the value is not shown in the report. So to include the column in your report but not make it visible on the screen, just concatenate it to an existing other column:
In your case, with the select from the question that would be:
select
APEX_ITEM.HIDDEN(3,ID) || APEX_ITEM.HIDDEN(2,FILENAME) || ID,
ROW_VERSION_NUMBER,
PROJECT_ID,
FILENAME,
FILE_MIMETYPE,
FILE_CHARSET,
FILE_BLOB,
FILE_COMMENTS,
TAGS,
CREATED,
CREATED_BY,
UPDATED,
UPDATED_BY,
APEX_ITEM.CHECKBOX(1,ID) checkbox
from EBA_DEMO_FILES
Note that filename can also be in a hidden element.

Related

How to find the specific record using sub query in SQL

I have a table in my Database in which Electronics part number information is saved. Against each part number, a Datasheet is attached with the Pdf file name and with its Publication date in next column.
There are some parts where pdf with different publication date is attached and I want to find out the Latest publication date pdf file.
Below is the code that I applied:
(
select v_prt_nbr_spr, max(s_gph_co_date), s_gph_file_name
from export1
where v_prt_nbr_spr = '747845-4'
group by v_prt_nbr_spr, s_gph_file_name
)
But I am getting multiple Pdf file name instead of the latest date as I am using group by clause..
Output:
v_prt_nbr_spr s_gph_co_date s_gph_file_name
747845-4 01-07-2001 TYELD00008.pdf
747845-4 14-03-2011 TYELS72963.pdf
747845-4 04-03-2016 TYEL-S-A0001601863.pdf
I want only TYEL-S-A0001601863.pdf name to show as it is the latest date pdf file.
You can try this:
select top 1
v_prt_nbr_spr, s_gph_co_date, s_gph_file_name
from export1
where v_prt_nbr_spr = '747845-4'
order by s_gph_co_date desc

After Update, Insert Trigger not working on Update SQL Server VB.net

I am building a personal comic book database and am having an issue with one of my SQL Server triggers.
My main comic entry (tabbed) form has a combo box for cover prices.
When the user clicks submit and inserts a comic into the database (comic_books table) on the comics entry page, I have a trigger that adds the cover price the user entered to a separate table (comic_prices table.) if the entry does not exist. This is working just fine.
However, I have a second tab ('Edit Comic') where the user can update an already inserted comic which uses a simple update script.
The user is able to change or add a new cover price of said comic from this tab also.
The issue I am having is that when the user clicks the 'Update Comic' button from the 'Edit Comic' tab, this newly entered comic price is not being inserted in the comic_prices table if it does not exist. So it looks like my trigger is only firing on my insert script and not on my update script.
Again, I have the trigger to only insert if the entry does not exist in the cover_prices table, otherwise it does nothing.
Please see my 'AFTER UPDATE, INSERT' trigger for this below and please let me know if you need any more information!
I appreciate any pointers or critiques!
DECLARE #cover_price varchar(50)
select #cover_price = cover_price from comic_books
If exists (SELECT cover_price FROM comic_prices where cover_price = #cover_price )
Begin
Return
End
IF not EXISTS (SELECT cover_price FROM comic_prices where cover_price = #cover_price)
INSERT INTO comic_prices(cover_price)VALUES(#cover_price)
UPDATE 04/22/17
After two or so weeks, I finally figured it out! I ended up making two separate triggers, one for the insert and another for the update. I kept the insert the same, however, the update looks like this:
DECLARE #publisher_name varchar(50)
--declare #comic_id bigint
select #publisher_name = inserted.issue_publisher from inserted
select #comic_id = comic_id from comic_books
If exists (select publisher_name from comic_publishers where publisher_name = #publisher_name)
Begin
return
End
IF not EXISTS (select publisher_name from comic_publishers where publisher_name = #publisher_name)
INSERT INTO comic_publishers (publisher_name)VALUES(#publisher_name)
I needed to tell the trigger to look for the inserted publisher!

SQL Update considering Null values

I am trying to update notes in a table to archive some files. I've generated the SQL script and am having a problem because of the accounts which have a Null value in the notes. I would like my note update to take place whether there is a Note or a Null in the current note field. Below is my SQL statement:
update dbo.CaseTable
set Quick = 'Case files have been archived. To have file access restored, please enter a helpdesk ticket with the full case name. '
+ convert(varchar(255),Quick)
where CaseID = 1
Try this:
update dbo.CaseTable
set Quick = 'Case files have been archived. To have file access restored, please enter a helpdesk ticket with the full case name. '
+ convert(varchar(255), ISNULL(Quick, ''))
where CaseID = 1
You can use CONCAT function. Null values are implicitly converted to an empty string.
Try this:
update dbo.CaseTable
set Quick = CONCAT('Case files have been archived. To have file access restored, please enter a helpdesk ticket with the full case name. ' , CAST(Quick AS varchar(255)))
where CaseID = 1
Update dbo.Case table
Set quick='case files has been archived.
To have files access restored,please enter
Helpdesk ticket with the fullcase name.'
+convert(varchar(255),ISNULL(Quick,"))
Where caseID=1

SqlDataAdapter taking too long to Fill VB.NET SQL Server 2012

I'm working on a winform application and I'm using a table named [File] in my SQL Server database.
I have a form that views some of "[File]" fields fID and fName in a combobox named SearchName. fID for Value and fName for Display.
SearchName Combobox is bound to dataset with dataadapter filling table with fID, fName, fPhoneNumber, fBalance, so I can use fName and fID.
I have also textboxes to add new "File" data like : fName, fAge, fNationality,fSex with a Save button with another combobox showing something called "Source".
When User clicks Save the data is saved to table [File] In DB and the adapter is filled again.
The dataset tableadapter was using a stored procedure as the following:
create proc [dbo].[ReadFileData](#fid int,#filter varchar(20))
as
begin
declare #f varchar(20)=#filter;
declare #id int =#fid;
if(#id=-1)
begin
if(#f='All')
select fID,fName,fPhoneNumbers,fBalance from [File]
else
if(#f='Blocked')
select fID,fName,fNotes,fBalance,fBlockDate,uFullName
from [File],[User] where fBlocked='True' and fBlocker=[uID]
order by fBlockDate desc
else
if(#f='nonBlocked')
select fID,fName,fPhoneNumbers,fBalance from [File] where fBlocked='False'
else
if(#f='notReady')
select fID,fName,fPhoneNumbers,fBalance from [File] where fAllTestsOK='False' and fBlocked='False'
else
if(#f='Ready')
select fID,fName,fPhoneNumbers,fBalance from [File] where fAllTestsOK='True' and fBlocked='False'
else
if(#f='NegBalanced')
select fID,fName,fPhoneNumbers,fBalance from [File] where fBalance<0
end
else
select f.fID,fName,fSex,fBirthDate,fPhoneNumbers,fAddress,fNationality,fNotes,fBalance,fBlocked,(select uFullName from [User] where uid=f.fBlocker) as fBlocker,
fLastEdited,(select uFullName from [User] where [uID]=f.fEditor) as fEditor, fBlockDate from [File] f where fID=#fid
end
It was taking too much time to save and fill the combobox again. I searched over the internet and I found out the problem is called "Patamter Sniffing/spoofing", because my procedure was selecting fields based on the values of the parameter it receives. I tried different ways to solve it, but nothing worked out for me. (P.S. I am using the same SP on other forms and data is filled immediately with no problems).
I deleted the whole dataset and created a new one with a new dataadapter using new Stored Procedure, this:
create proc [dbo].[GetAllFiles]
as
begin
select fID,fName,fPhoneNumbers,fBalance from [File]
end
Now first time the save and fill is done in no time, but after that it takes like 10+ seconds to fill.
I want to know what can I do to continue using the dataadapter to fill the combobox and solve time consuming problem?
If you have any suspicions that might cause these kind of problems, please let me know.
What other code parts or even design pictures can I provide to make my problem clearer?
Thanks to #Plutonix. He wrote it in a reply, just to make it clearer.
"You should spend a few hours on MSDN. You do not need to requery/refill/rebuild a datatable when you add rows; they can be refreshed. – Plutonix"
I used DataAdapterName.Adapter.Update(DatasetName) in save button and other update places. And kept fill only in page load event.

Multiple file upload blueimp “sequentialUploads = true” not working

I have to store multiple files in a Database. In order to do that I am using jQuery Multiple File Uplaod control written by blueimp. For the server language I use asp.net. It uses a handler – ashx which accepts every particular file and stores it in the DB.
In my DB I have a stored procedure which returns the document id of the currently uploaded file and then stores it into the DB.
This is a code fragment from it which shows that getting this id is a 3 step procedure:
SELECT TOP 1 #docIdOut = tblFile.docId --
,#creator=creator,#created=created FROM [tblFile] WHERE
friendlyname LIKE #friendlyname AND #categoryId = categoryId AND
#objectId = objectId AND #objectTypeId = objectTypeId ORDER BY
tblFile.version DESC
IF #docIdOut = 0 BEGIN --get the next docId SELECT TOP 1
#docIdOut = docId + 1 FROM [tblFile] ORDER BY docId DESC END
IF #docIdOut = 0 BEGIN --set to 1 SET #docIdOut = 1 END
If more than one calls to that stored procedure are executed then will be a problem due to inconsistency of the data, but If I add a transaction then the upload for some files will be cancelled.
https://dl.dropboxusercontent.com/u/13878369/2013-05-20_1731.png
Is there a way to call the stored procedure again with the same parameters when the execution is blocked by transaction?
Another option is to use the blueimp plugin synchronously with the option “sequentialUploads = true”
This option works for all browsers except firefox, and I read that it doesn’t work for Safari as well.
Any suggestions would be helpful. I tried and enabling the option for selecting only one file at a time, which is not the best, but will stop the DB problems (strored procedure) and will save the files correctly.
Thanks,
Best Regards,
Lyuubomir
set singleFileUploads: true, sequentialUploads: false in the main.js.
singleFileUploads: true means each file of a selection is uploaded using an individual request for XHR type uploads. Then you can get information of an individual file and call the store procedure with the information you have just got.

Resources