Question

I am trying to use the APEX data loader to allow users to import data and one of the column values I would rather not force the users to provide since the value is readily available in the session when the users selects import.Is there a way to add that column value programmatically?

Was it helpful?

Solution 3

You could edit the loader and add a data transformation rule.

I hate to just post a link but this blog post from Rowan provides ample explanation how this works since the documentation from Oracle does not.

Application Express Data Loader Transformation Rules in 4.2

Basically, the transformation rules feature allows you to select one or more columns in your target table. You then choose the type of transformation from the available options: PL/SQL expression, PL/SQL Function, SQL Query (2 types her).

The loader will run this function for each row loaded and you can reference session state, lookup values in other tables or package state, as well as column values in the row. For example if you have a column named COLUMN1 you would refer to it in the source of the transformation rule as :COLUMN1 (e.g IF :COLUMN1 > 10 THEN .... ).

If you use the PL/SQL Expression, the value after evaluation will be returned as the new column value. If you use PL/SQL Function you will need to add a RETURN expression to get this value back tot he column.

That is to say that you will not be able to set the values using the bind notation you use to get values. So if you want COLUMN1 to be set to 10, build a rule to set that value, don't try to do :COLUMN1 := 10; as this state will only last during the execution of your rule for the record being transformed.

OTHER TIPS

With the Oracle APEX 4.2 data wizard, adding the rows to the SPREADSHEET_CONTENT is not enough if the First Rows are the column names. You also have to run the following assuming you are adding a 9th column, 'C009' and the name is 'MY_COLUMN_NAME'.

APEX_COLLECTION.ADD_MEMBER(
        p_collection_name => 'PARSE_COL_HEAD',
        p_c001            => 'C009',
        p_c002            => 'MY_COLUMN_NAME')
;

Otherwise, it just ignores the data as it's using the meta data of PARSE_COL_HEAD.

I had a similar issue and solved it along the lines that Greg suggested in his comment. Here is a sample of the code I used in the process that runs right after "Parse Uploaded Data" on page 1 of the wizard:

FOR UPLOAD_ROW IN (SELECT SEQ_ID
                   FROM APEX_COLLECTIONS
                   WHERE COLLECTION_NAME = 'SPREADSHEET_CONTENT')
LOOP
 APEX_COLLECTION.UPDATE_MEMBER_ATTRIBUTE (
    p_collection_name   => 'SPREADSHEET_CONTENT',
    p_seq               => UPLOAD_ROW.SEQ_ID,
    p_attr_number       => '2',
    p_attr_value        => :P1_TABLE_FIELD_2);

 APEX_COLLECTION.UPDATE_MEMBER_ATTRIBUTE (
    p_collection_name   => 'SPREADSHEET_CONTENT',
    p_seq               => UPLOAD_ROW.SEQ_ID,
    p_attr_number       => '3',
    p_attr_value        => :P1_TABLE_FIELD_3);

 APEX_COLLECTION.UPDATE_MEMBER_ATTRIBUTE (
    p_collection_name   => 'SPREADSHEET_CONTENT',
    p_seq               => UPLOAD_ROW.SEQ_ID,
    p_attr_number       => '4',
    p_attr_value        => :P1_TABLE_FIELD_4);
END LOOP;

For a more detailed explanation see http://www.jrweth.com/oracle-apex-data-loader-part-1-adding-custom-columns/

This new code is working perfectly despite the USE_APPLICATION_DATE_FORMAT column added by APEX. Note that near the bottom of the code the p_seq is set to '35'.

Declare
v_date date;

BEGIN

SELECT SYSDATE INTO v_date FROM Dual;

APEX_COLLECTION.ADD_MEMBER(
p_collection_name => 'PARSE_COL_HEAD',
p_c001 => 'C036',
p_c002 => 'UPLOAD_DTE');

APEX_COLLECTION.MOVE_MEMBER_DOWN(
p_collection_name =>'PARSE_COL_HEAD',
p_seq => '36');

FOR UPLOAD_ROW IN (SELECT SEQ_ID FROM APEX_COLLECTIONS
                   WHERE COLLECTION_NAME = 'SPREADSHEET_CONTENT')
LOOP

APEX_COLLECTION.UPDATE_MEMBER_ATTRIBUTE (
p_collection_name => 'SPREADSHEET_CONTENT',
p_seq => UPLOAD_ROW.SEQ_ID,
p_attr_number => '35',
p_attr_value => v_date);
END LOOP;

END;

For Oracle APEX data loader 4.2, in the developer view, look on the 1st page, in the 'Page Processing' block, right click on "Processing" and select "add new process" , then name it. Mine is called 'add_column', then add the below code.enter image description here

You need to first add a new column to the APEX collection. You can do APEX_COLLECTION.ADD_MEMBER() function. In the code below, I add in an additional column at column 31 location and the name of the column is called 'FILE_DATE'. This is the same as the name as the column the database table.

After that you loop through each row by SEQ_ID and update column 31 with a value. In my case, I wanted to get the filename, which was :P25_FILE_NAME

When you run the pages, you can click on 'Session' on the developer toolbar at the bottom to have a look at the APEX collection array and see if your column is getting populated correctly.

BEGIN

APEX_COLLECTION.ADD_MEMBER
(
        p_collection_name => 'PARSE_COL_HEAD',
        p_c001            => 'C031',
        p_c002            => 'FILE_DATE');

FOR UPLOAD_ROW IN (SELECT SEQ_ID FROM APEX_COLLECTIONS 
                   WHERE COLLECTION_NAME = 'SPREADSHEET_CONTENT')
LOOP

  APEX_COLLECTION.UPDATE_MEMBER_ATTRIBUTE (
   p_collection_name  => 'SPREADSHEET_CONTENT',
   p_seq              => UPLOAD_ROW.SEQ_ID,
   p_attr_number      => '31',
   p_attr_value       => :P25_FILE_NAME
  ); 

END LOOP;

END;

I am able to get through it using the code below:

Declare
v_count number(10);
BEGIN

APEX_COLLECTION.ADD_MEMBER(
p_collection_name => 'PARSE_COL_HEAD',
p_c001 => 'SESSION_ID');

v_count:=APEX_COLLECTION.COLLECTION_MEMBER_COUNT ('PARSE_COL_HEAD');

v_count:=v_count+1;

FOR UPLOAD_ROW IN (SELECT SEQ_ID
FROM APEX_COLLECTIONS
WHERE COLLECTION_NAME = 'SPREADSHEET_CONTENT')
LOOP

APEX_COLLECTION.UPDATE_MEMBER_ATTRIBUTE (
p_collection_name => 'SPREADSHEET_CONTENT',
p_seq => UPLOAD_ROW.SEQ_ID,
p_attr_number => v_count,
p_attr_value => V('APP_SESSION')); –-I was trying to load session id
END LOOP;

END;

So it's now 2017 and the APEX 5.0.4.00.12 Data Load Wizard has a new weird feature. If you include a date field in your upload, there's an extra column already added to your PARSE_COL_HEAD collection, C001 = USE_APPLICATION_DATE_FORMAT, C002 = E. This "E" column name shows up in the table mapping page rather than the new column you are trying to add. If you select/map your alias the file uploads correctly (using Tikkaty's example above), but the "E" is far from user friendly. In my case the "E" shows up in column 35, and the column I'm adding has to be made 36th.

After sleeping on it, here's how I fixed it:

Declare
v_date date;

BEGIN

SELECT SYSDATE INTO v_date FROM Dual;

APEX_COLLECTION.ADD_MEMBER(
p_collection_name => 'PARSE_COL_HEAD',
p_c001 => 'C036',
p_c002 => 'UPLOAD_DTE');

APEX_COLLECTION.MOVE_MEMBER_DOWN(
p_collection_name =>'PARSE_COL_HEAD',
p_seq => '36');

FOR UPLOAD_ROW IN (SELECT SEQ_ID FROM APEX_COLLECTIONS
                  WHERE COLLECTION_NAME = 'SPREADSHEET_CONTENT')
LOOP

APEX_COLLECTION.UPDATE_MEMBER_ATTRIBUTE (
p_collection_name => 'SPREADSHEET_CONTENT',
p_seq => UPLOAD_ROW.SEQ_ID,
p_attr_number => '35',
p_attr_value => v_date);

END LOOP;

END;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top