AboutElliot Mak Expertise I can answer questions with regarding to Oracle DB (8i, 9i, 10g) installation, configuration, administration, Data Guard, SQL, and PL/SQL (Procedures, triggers, functions).
Experience I am an Oracle DBA, Senior PA, Project Manager, and Data Architect with 10 years of experience.
Question QUESTION: Hello Sir,
I want a help in creating dynamic table as per the csv file. The csv file which is to be uploaded does not have a fixed format (No. of columns). So I want to create table with the same number of column as present in the csv file.
This whole thing has to be incorporated inside a stored procedure with upload of file.
Thanks,
Rocky
ANSWER: Good day Rocky,
I will need to make some assumption based on your question.
1. A new table will be generated everytime it loads
2. These tables are permanent tables
3. These tables are not for temporary data loading
4. You are using Oracle 10gR2 and above
5. Different files may have different # of columns.
6. All the rows in the same file have the same # of columns.
Here is what I will do in this situation using PL/SQL
Setup
1. Create an external table that link the source of the table to a CSV. This external table contains only one column.
PL/SQL
1. In your PL/SQL, open a cursor for the external table
2. Get the first row from the external table and check # of columns in the table (by counting the comma delimiter)
3. Construct a create statement for the permanent table with the correct # of columns
4. Use EXECUTE IMMEDIATE command to execute the create statement above
5. Use a while loop to parse each rows from the external table and then insert it into the permanent table.
You can modularized each of those steps so that you can reuse them in your other PL/SQL program.
Of course, there may be another way to do it, but I will do it this way myself.
Hope it helps, and if you shall have additional questions, please don't hesitate to let me know
Cheers
Elliot
---------- FOLLOW-UP ----------
QUESTION: Hi Elliot,
Thanks for you reply. Actually the database I am using is Oracle 9.2. And whatever you had guessed is all right. Basically I am a Java developer and knows very little in oracle. Through my search on net I was able to try my hands on SQl Loader and External tables. Will you please elaborate on your steps more, so that I can try it at my end.
Thanks,
Rocky.
Answer Good day Rocky
If you are using v9.2, you may not have the ability to create an external table. I believe this is available from 10g onwards. I don't have a 9i environment to help you out in this regards, but I can certainly based it on 10g.
Question #1: Is it mandatory to use Oracle 9i? 10gR2 or even 11g is much better and provide more functionalities than 9i.
****************************************
Setup the external table (10g and above)
****************************************
Assume the following:
- Oracle User and Schema name is ALLEXPERTS
- Database name is EXPERTS
- The directory object is file_dir
- CSV file directory is /export/home/log
- The csv file name is ALLEXPERTS_CSV.log
- The table name is all_experts_tbl
1. Create a directory object in Oracle. The directory will point to the directory where the file located.
conn sys/{password}@EXPERTS as sysdba;
CREATE OR REPLACE DIRECTORY file_dir AS '/export/home/log';
2. Grant the directory privilege to the user
GRANT READ ON DIRECTORY file_dir TO ALLEXPERTS;
This will create a table that links the data to a file. Now you can treat this file as a regular table where you can use SELECT statement to retrieve the data.
****************************************
PL/SQL to create the data (PSEUDO code)
****************************************
CREATE OR REPLACE PROCEDURE new_proc IS
-- Setup the cursor
CURSOR c_main IS SELECT *
FROM allexperts.all_experts_tbl;
CURSOR c_first_row IS ALLEXPERTS_CSV.logSELECT *
FROM allexperts.all_experts_tbl
WHERE ROWNUM = 1;
-- Get the first row
-- Open the c_first_row and fetch the data into l_current_row
-- Count the number of delimiter l_current_row and set the l_delimiter_count
OPEN c_first_row;
FETCH c_first_row INTO l_current_row;
CLOSE c_first_row;
l_delimiter_count := number of delimiter in l_current_row;
-- Create the table with the right number of columns
l_create_statements := 'CREATE TABLE csv_table ( ';