Comments on: Read an Excel xlsx with PL/SQL https://technology.amis.nl/2013/01/19/read-a-excel-xlsx-with-plsql/ Friends of Oracle and Java Wed, 08 Jul 2015 07:37:03 +0000 hourly 1 http://wordpress.org/?v=4.2.3 By: Anton Scheffer https://technology.amis.nl/2013/01/19/read-a-excel-xlsx-with-plsql/#comment-8220 Wed, 03 Jun 2015 19:28:54 +0000 http://technology.amis.nl/?p=20612#comment-8220 @Sagay. The max size of a varchar2 in a SQL-query is 4000 characters. If your excel contains larger strings you will get that error. I don’t handle that in purpose. If you do want to truncate those values, just change that line to t_one_cell.string_val := substr( t_strings( to_number( t_val ) ), 1, 4000 );

]]>
By: Sagay https://technology.amis.nl/2013/01/19/read-a-excel-xlsx-with-plsql/#comment-8219 Wed, 03 Jun 2015 16:21:51 +0000 http://technology.amis.nl/?p=20612#comment-8219 @Anton – Thanks for the package. It is parsing the Excel file as expected.

When I run the given query in SQL developer, after returning few 100 rows it hits “ORA-06502: PL/SQL: numeric or value error: character string buffer too small” at line 296 of the package.

Can you please help?

]]>
By: Nicolas Denis https://technology.amis.nl/2013/01/19/read-a-excel-xlsx-with-plsql/#comment-8183 Thu, 23 Apr 2015 12:54:46 +0000 http://technology.amis.nl/?p=20612#comment-8183 Here the way I proceed the Excel once loaded. I use this to rebuild the matrix to its original state using a single SQL query.
I dump the excel into a Global Temporary table for faster access, detect the “header” row (it may not be the first row) and rebuild my matrix with a query similar to:

SELECT MAX(DECODE(col_nr, 1, TRIM(string_val), NULL)) COL_A,
MAX(DECODE(col_nr, 2, TRIM(string_val), NULL)) COL_B
FROM GLOBAL_TEMPORARY_TABLE
WHERE SHEET_NAME = ‘My Sheet’
AND ROW_NR > nFirstRowID
GROUP BY ROW_NR;

That way, even if the package do not read empty cell – the output you get include the blank column with NULL.
Use “string_val”, “number_val” or “date_val” in the query depending with datatype you expect.

Hope this will help

]]>
By: Anton Scheffer https://technology.amis.nl/2013/01/19/read-a-excel-xlsx-with-plsql/#comment-8182 Thu, 23 Apr 2015 10:31:08 +0000 http://technology.amis.nl/?p=20612#comment-8182 In my opinion that doesn’t need to be fixed. The package reads values stored in a Excel file. If a column only contains a “column name”, that means there’s nothing stored in the other rows (for that column). And that means no output from this package. But if you know that the Excel contains a matrix, and you expect null values for empty cells, YOU can change the query to add those values, outer joining it to something for instance. But feel free to change to package yourself to fix it.

]]>
By: CUGAR https://technology.amis.nl/2013/01/19/read-a-excel-xlsx-with-plsql/#comment-8181 Wed, 22 Apr 2015 10:03:28 +0000 http://technology.amis.nl/?p=20612#comment-8181 Hi, this is great package, but I have one problem.

When column in excel file contains only column name (in first row) and rest of values in taht column contaions NULLs, package will read only column name and maybe one more row with Null value.
It will not read other NULL’s values from that column.

How can it be fixed?

]]>
By: Alberto https://technology.amis.nl/2013/01/19/read-a-excel-xlsx-with-plsql/#comment-8154 Tue, 31 Mar 2015 17:57:32 +0000 http://technology.amis.nl/?p=20612#comment-8154 Resolved, understood as change this directory, thank you. http://www.tuinformaticafacil.com/oracle-11g/como-crear-y-administrar-objetos-directory-en-oracle

]]>
By: Alberto https://technology.amis.nl/2013/01/19/read-a-excel-xlsx-with-plsql/#comment-8153 Tue, 31 Mar 2015 17:33:40 +0000 http://technology.amis.nl/?p=20612#comment-8153 Hello Anton,
you could be a little more specific when you say “DOC” in which directory server database references? as could change this path. thanks for this great contribution

]]>
By: Andrew https://technology.amis.nl/2013/01/19/read-a-excel-xlsx-with-plsql/#comment-8135 Thu, 12 Mar 2015 14:50:59 +0000 http://technology.amis.nl/?p=20612#comment-8135 I haven’t noticed any continued degradation after that fix but it may be possible the memory for the blobs are not released as well. Perhaps my files are not large enough to notice a difference.

There is this line which may have a similar effect since it is using a function to pass as a parameter.

t_nd := blob2node( get_file( p_xlsx, ‘xl/workbook.xml’ ) );

Perhaps setting the get_file() call to a local variable first will have an effect but that is just speculation right now. You may have to search through the code to find instances like that and try it out.

]]>
By: Martin Goblet https://technology.amis.nl/2013/01/19/read-a-excel-xlsx-with-plsql/#comment-8134 Thu, 12 Mar 2015 14:35:55 +0000 http://technology.amis.nl/?p=20612#comment-8134 Andrew

I didn’t see you post before :( Tried your solution, but the elapsed time still increases (a little bit less now) by each run. Could it be possible that the BLOB parameters memory is never reset (p_xlsx, p_blob, p_zipped_blob) ?

Regards
Martin

]]>
By: mago28 https://technology.amis.nl/2013/01/19/read-a-excel-xlsx-with-plsql/#comment-8133 Thu, 12 Mar 2015 12:49:42 +0000 http://technology.amis.nl/?p=20612#comment-8133 Thanks.

]]>
By: Andrew https://technology.amis.nl/2013/01/19/read-a-excel-xlsx-with-plsql/#comment-8132 Thu, 12 Mar 2015 12:30:00 +0000 http://technology.amis.nl/?p=20612#comment-8132 Martin,
I experienced the elapsed time increase with successive runs as well. There is a memory leak because a call to dbms_xmldom.getdocumentelement() is used as a parameter in a call to dbms_xmldom.newdocument(). The allocated memory is not released.
I made a fix for that by using a local variable t_ndoc for the getdocumentelement() call and then explicitly freeing the memory.

See my post on Oct 11, 2013.

-–return dbms_xmldom.makenode( dbms_xmldom.getdocumentelement( –dbms_xmldom.newdomdocument( xmltype( p_blob, nls_charset_id( ‘AL32UTF8′ ) ) ) ) );

t_ndoc := dbms_xmldom.newdomdocument( xmltype( p_blob, nls_charset_id( ‘AL32UTF8′ ) ) );
return dbms_xmldom.makenode( dbms_xmldom.getdocumentelement( t_ndoc ) );

]]>
By: Martin Goblet https://technology.amis.nl/2013/01/19/read-a-excel-xlsx-with-plsql/#comment-8131 Thu, 12 Mar 2015 09:25:05 +0000 http://technology.amis.nl/?p=20612#comment-8131 I do it this way :

SELECT MAX(DECODE(col_nr, 1, SUBSTR(string_val, 1, 10), ”)) cod_taric
, MAX(DECODE(col_nr, 1, SUBSTR(string_val, 12, 2), ”)) genre
, MAX(DECODE(col_nr, 2, date_val, ”)) dat_valid_from
, MAX(DECODE(col_nr, 3, string_val, ”)) utilisable
FROM AS_READ…
WHERE sheet_nr = 1 AND row_nr > 1 — Void description line
GROUP BY sheet_nr, row_nr
ORDER BY sheet_nr, row_nr;

]]>
By: Martin Goblet https://technology.amis.nl/2013/01/19/read-a-excel-xlsx-with-plsql/#comment-8130 Thu, 12 Mar 2015 08:50:48 +0000 http://technology.amis.nl/?p=20612#comment-8130 Hi Anton

Again, many thanks for this wonderful package (and for the as_zip too)

Just a little correction, because I got a error on a huge string : added a substr(…, 1, 4000) on 2 lines

IF t_t IN (‘str’, ‘inlineStr’, ‘e’) THEN
t_one_cell.cell_type := ‘S';
t_one_cell.string_val := SUBSTR(t_val, 1, 4000);
ELSIF t_t = ‘s’ THEN
t_one_cell.cell_type := ‘S';

IF t_val IS NOT NULL THEN
t_one_cell.string_val := SUBSTR(t_strings(TO_NUMBER(t_val)), 1, 4000);
END IF;
ELSE

An other problem I noticed : when I run the procedure several times, it takes more time at each run. When I often run it on large xlsx files, I’ve to close my session and reopen it to start from scratch.

I guess that some memory is not freed up (DBMS_LOB.freetemporary, DBMS_SESSION.free_unused_user_memory, …) somewhere ?

Regards
Martin

]]>
By: Herbert Broich https://technology.amis.nl/2013/01/19/read-a-excel-xlsx-with-plsql/#comment-8129 Thu, 12 Mar 2015 08:04:07 +0000 http://technology.amis.nl/?p=20612#comment-8129 Thanks a lot!
This version works very well!

]]>
By: Anton Scheffer https://technology.amis.nl/2013/01/19/read-a-excel-xlsx-with-plsql/#comment-8127 Tue, 10 Mar 2015 15:41:29 +0000 http://technology.amis.nl/?p=20612#comment-8127 The latest version is linked in this blog.

]]>