While loop doesn't exit when eof is detected - while-loop

I'm having troubles with the eof sequence at the while loop. Basically I have to read a txt file (sequence) and each character has a different character that will be printed on an exit.txt file. But my while loop doesn't recognize the eof. Here's my code.
program LaboratorioPascal;
uses crt;
var
sec, sal: Textfile;
v: char;
por_especial, cont_palabra, cont_caracter, cont_especial: integer;
vocales2: set of char;
pares: set of char;
impares: set of char;
consonantes: set of char;
consonantes2: set of char;
procedure numeros(var x: char);
begin
case x of
'0': Write(sal, '0');
'1': Write(sal, '1');
'2': Write(sal, '4');
'3': begin
Write(sal, '2');
Write(sal, '7');
end;
'4': Write(sal, '8');
'5': begin
Write(sal, '1');
Write(sal, '2');
Write(sal, '5');
end;
'6': begin
Write(sal, '1');
Write(sal, '2');
end;
'7': begin
Write(sal, '3');
Write(sal, '4');
Write(sal, '3');
end;
'8': begin
Write(sal, '1');
Write(sal, '6');
end;
'9': begin
Write(sal, '7');
Write(sal, '2');
Write(sal, '9');
end;
else Exit;
end;
end;
function vocales(var s: char): char;
begin
case s of
'e': vocales := 'u';
'a': vocales := 'o';
'i': vocales := 'a';
'o': vocales := 'e';
else vocales := 'i';
end;
end;
begin
assign(sec, 'input.txt'); // Le asignamos un archivo del cual lea
reset(sec); // arrancamos la secuencia
read(sec, v); // leemos la secuencia. avz(sec, v)
assign(sal, 'salida.txt');
rewrite(sal);
vocales2 := ['a', 'e', 'i', 'o', 'u'];
pares := ['0', '2', '4', '6', '8'];
impares := ['1', '3', '5', '7', '9'];
consonantes := ['b', 'c', 'd', 'f', 'g', 'h', 'j','k','l','m', 'n'];
consonantes2 := ['p', 'q', 'r', 's', 't', 'v', 'w', 'x', 'y', 'z'];
por_especial := 0;
cont_palabra := 0;
cont_caracter := 0;
cont_especial := 0;
writeln('El objetivo de este programa es cifrar un mensaje para favorecer a la inteligencia Rusa.');
while not eof(sec) do
begin
while v = ' ' do
begin
write(sal, ' ');
read(sec, v);
end;
cont_palabra := cont_palabra + 1;
while v <> ' ' do
begin
if (v in consonantes) or (v in consonantes2) then
begin
write(sal, '1');
end
else
begin
if v in vocales2 then
begin
Write(sal, vocales(v));
end
else
begin
if v in pares then;
begin
numeros(v);
end;
begin
if v in impares then
begin
numeros(v);
end
else
begin
cont_especial := cont_especial + 1;
Write(sal, '#');
end;
end;
end;
end;
read(sec, v);
end;
end;
write(cont_palabra, ' se crifraon con [Exito]');
close(sec);
close(sal);
end.
But the result I have in the exit file (salida.txt) is
1o1ao i1o 1u1 i1 1e1111ie 1iu 1u 1e1ae o i1o 11a11u1o### 1a1########################################################################################################################################################################################################
I've done my research about the eof topic, but I can't find anything about pascal. And if I try to put an
if eof then
Exit;
end;
inside the while loop, and it just read one character from the input.txt file.

The problem is that you are in the inner loop ("while v <> ' ' do") when you come to the end of your input file.
If the last character in the input file is a space, you jump out of the inner loop and out of the outer loop, because you reached eof.
But if it isn't, you stay in the inner loop, and keep reading beyond the eof, until you encounter a space or a problem.
You can change the inner loop's
"while v <> ' ' do"
to
"while (v <> ' ') and (not eof(sec)) do".
Or make it one loop and handle the space in an if statement.

Related

Trying to update substrings in SQL

Can anyone help with some SQL syntax?
I have a table (TABLE A) which contains a 54 character field (FIELD A) which in essence contains 8x6 blocks of data.
These can be broken down into substrings:
substr(FIELD A,1,6) as A
substr(FIELD A,7,6) as B
substr(FIELD A,13,6) as C
substr(FIELD A,19,6) as D
substr(FIELD A,25,6) as E
substr(FIELD A,31,6) as F
substr(FIELD A,37,6) as G
substr(FIELD A,43,6) as H
substr(FIELD A,49,6) as I
What I need to do is if there an occurrence of '404040' in any of these substring fields (A to I), replace them with '000000'. The '404040' has to be in these exact positions, not just a 'like %404040%' anywhere in FIELD A. I don't think I can perform an Update on a substring(?) but my efforts at using the Replace haven't yet worked. Can anyone suggest a solution?
I'm using SQL Developer 3.2.20.10 and Oracle 12.
Many Thanks AP
You can achieve this using two functions Replacepos to replace the string at the position and replacepos1 to mention the no_of_chars to be replaced.After that you can just use the below SQL
WITH data
AS (SELECT ROWNUM rw,
Lpad('404040', 54, '404040') A
FROM dual),
d1
AS (SELECT rw,
Decode(Instr(a, '404040', 1), 1, Replacepos1(a, '0', 1, 6)) A
FROM data),
d2
AS (SELECT rw,
Decode(Instr(a, '404040', 1), 7, Replacepos1(a, '0', 7, 6)) A
FROM d1),
d3
AS (SELECT rw,
Decode(Instr(a, '404040', 1), 13, Replacepos1(a, '0', 13, 6))A
FROM d2),
d4
AS (SELECT rw,
Decode(Instr(a, '404040', 1), 19, Replacepos1(a, '0', 19, 6))A
FROM d3),
d5
AS (SELECT rw,
Decode(Instr(a, '404040', 1), 25, Replacepos1(a, '0', 25, 6))A
FROM d4),
d6
AS (SELECT rw,
Decode(Instr(a, '404040', 1), 31, Replacepos1(a, '0', 31, 6))A
FROM d5),
d7
AS (SELECT rw,
Decode(Instr(a, '404040', 1), 37, Replacepos1(a, '0', 37, 6))A
FROM d6),
d8
AS (SELECT rw,
Decode(Instr(a, '404040', 1), 43, Replacepos1(a, '0', 43, 6))A
FROM d7),
d9
AS (SELECT rw,
Decode(Instr(a, '404040', 1), 49, Replacepos1(a, '0', 49, 6))A
FROM d8)
SELECT A
FROM d9;
The Functions specifications below
CREATE OR replace FUNCTION Replacepos(source_in IN VARCHAR2,
replacechar_in IN VARCHAR2,
position_start IN NUMBER)
RETURN VARCHAR2
IS
l_returnvalue VARCHAR2(32767);
position_in NUMBER;
BEGIN
-- copy from the source string up to, but not including,
-- the character position
position_in := position_start;
-- to be replaced
l_returnvalue := Substr(str1 => source_in, pos => 1, len => position_in - 1)
;
-- add the replacement character
-- just a single character, but more can be sent in,
-- so substring the parameter
l_returnvalue := l_returnvalue
|| Substr(str1 => replacechar_in, pos => 1, len => 1);
-- copy the rest of the source string
l_returnvalue := l_returnvalue
|| Substr(str1 => source_in, pos => position_in + 1);
RETURN l_returnvalue;
END replacepos;
AND the below function
CREATE OR replace FUNCTION Replacepos1 (source_in IN VARCHAR2,
replacechar_in IN VARCHAR2,
position_start IN NUMBER,
no_of_chars IN NUMBER)
RETURN VARCHAR2
IS
l_returnvalue VARCHAR2(32767);
position_in NUMBER;
BEGIN
l_returnvalue := source_in;
FOR i IN 1..no_of_chars LOOP
l_returnvalue := Replacepos(l_returnvalue, replacechar_in,
position_start + i - 1);
END LOOP;

SQL Server - Find frequency of occurance (by row, not word) of most common words in a column

This question has been asked more than a few times, but I can't find the specific answer I need. I have a query that finds the most commonly appearing words in a column in SQL Server and lists them with the count of their appearances. The problem is that if a word appears multiple times in a row, it counts once for each appearance. I would like to only count each word once per row.
So a row with a value of "To be or not to be" would count 'to' and 'be' once each, not twice each for purposes of overall frequency.
Here is the current query, which also strips out common words such as pronouns and replaces all of the commonly occurring separators with spaces. It's a bit old so I suspect it could be a lot neater.
SELECT sep.Col Phrase, count(*) as Qty
FROM (
Select * FROM (
Select value = Upper(RTrim(LTrim(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Title, ',', ' '), '.', ' '), '!', ' '), '+', ' '), ':', ' '), '-', ' '), ';', ' '), '(', ' '), ')', ' '), '/', ' '), '&', ''), '?', ' '), ' ', ' '), ' ', ' '))))
FROM Table
) easyValues
Where value <> ''
) actualValues
Cross Apply dbo.SeparateValues(value, ' ') sep
WHERE sep.Col not in ('', 'THE', 'A', 'AN', 'WHO', 'BOOK', 'AND', 'FOR', 'ON', 'HAVE', 'YOUR', 'HOW', 'WE', 'IN', 'I', 'IT', 'BY', 'SO', 'THEIR', 'IS', 'OR', 'HE', 'OF', 'WHAT'
, 'HIM', 'HIS', 'SHE', 'HER', 'MY', 'FROM', 'US', 'OUR', 'AT', 'ALL', 'BE', 'OF', 'TO', 'YOU', 'WITH', 'THAT', 'THIS', 'WAS', 'ARE', 'THERE', 'BUT', 'HAS'
, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 'WILL', 'MORE', 'DIV', 'THAN', 'EACH', 'GET', 'ANY')
and LEN(sep.Col) > 2
GROUP By sep.Col
HAVING count(*) > 1
Appreciate any thoughts on a better way to do this while fixing the issue of repeat words.
You just need to GROUP BY twice.
First by sep.Col and Table.ID to remove duplicates in a row. Your table has some ID column, right?
Second, just by sep.Col to get the final count.
I have also rewritten your query using CTEs to make it readable. At least, for me it is more readable in this way.
WITH
easyValues
AS
(
Select
ID
,value = Upper(RTrim(LTrim(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Title, ',', ' '), '.', ' '), '!', ' '), '+', ' '), ':', ' '), '-', ' '), ';', ' '), '(', ' '), ')', ' '), '/', ' '), '&', ''), '?', ' '), ' ', ' '), ' ', ' '))))
FROM Table
)
,actualValues
AS
(
SELECT
ID
,Value
FROM easyValues
Where value <> ''
)
,SeparateValues
AS
(
SELECT
ID
,sep.Col
FROM
actualValues
Cross Apply dbo.SeparateValues(value, ' ') AS sep
WHERE
sep.Col not in ('', 'THE', 'A', 'AN', 'WHO', 'BOOK', 'AND', 'FOR', 'ON', 'HAVE', 'YOUR', 'HOW', 'WE', 'IN', 'I', 'IT', 'BY', 'SO', 'THEIR', 'IS', 'OR', 'HE', 'OF', 'WHAT'
, 'HIM', 'HIS', 'SHE', 'HER', 'MY', 'FROM', 'US', 'OUR', 'AT', 'ALL', 'BE', 'OF', 'TO', 'YOU', 'WITH', 'THAT', 'THIS', 'WAS', 'ARE', 'THERE', 'BUT', 'HAS'
, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 'WILL', 'MORE', 'DIV', 'THAN', 'EACH', 'GET', 'ANY')
and LEN(sep.Col) > 2
)
,UniqueValues
AS
(
SELECT
ID, Col
FROM
SeparateValues
GROUP BY
ID, Col
)
SELECT
Col AS Phrase
,count(*) as Qty
FROM UniqueValues
GROUP By Col
HAVING count(*) > 1
;
As far as I can tell, the STRING_SPLIT function along with CROSS APPLY can give you what you want. You can split the string based on the space delimiter, select each word distinctly, then count in an outer query. I ommitted the part where you don't select specific words for brevity.
Fiddle<>:
CREATE TABLE phrases(phrase NVARCHAR(MAX));
INSERT INTO phrases(phrase)VALUES(N'To be or not to be'),(N'this is not a phrase'),(N'And why is this not another one');
SELECT
w.value,
COUNT(*)
FROM
phrases AS p
CROSS APPLY (
SELECT DISTINCT
value
FROM
STRING_SPLIT(p.phrase,N' ')
) AS w
GROUP BY
w.value;
To achieve your requirement, you can use a FUNCTION to split a string into list of words by delimiter ' ' space. With the help of this function, you can then use some Dynamic SQL like cursor to get the final count.
First create the FUNCTION as-
Source Of code: stackoverflow
CREATE FUNCTION dbo.splitstring ( #stringToSplit VARCHAR(MAX) )
RETURNS #returnList TABLE ([Word] [nvarchar] (500))
AS
BEGIN
DECLARE #name NVARCHAR(255)
DECLARE #pos INT
WHILE CHARINDEX(' ', #stringToSplit) > 0
BEGIN
SELECT #pos = CHARINDEX(' ', #stringToSplit)
SELECT #name = SUBSTRING(#stringToSplit, 1, #pos-1)
INSERT INTO #returnList
SELECT #name
SELECT #stringToSplit = SUBSTRING(#stringToSplit, #pos+1, LEN(#stringToSplit)-#pos)
END
INSERT INTO #returnList
SELECT #stringToSplit
RETURN
END
Then use this CURSOR script to get your final output-
DECLARE #Value VARCHAR(MAX)
DECLARE #WordList TABLE
(
Word VARCHAR(200)
)
DECLARE db_cursor CURSOR
FOR
SELECT Upper(RTrim(LTrim(Replace(Replace(Replace(Replace(Replace
(Replace(Replace(Replace(Replace(Replace(Replace(Replace
(Replace(Replace(title, ',', ' '), '.', ' '), '!', ' '), '+', ' '), ':', ' '), '-', ' '), ';', ' ')
, '(', ' '), ')', ' '), '/', ' '), '&', ''), '?', ' '), ' ', ' '), ' ', ' ')))) [Value]
FROM table
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO #Value
WHILE ##FETCH_STATUS = 0
BEGIN
INSERT INTO #WordList
SELECT DISTINCT Word FROM [dbo].[splitstring](#Value)
WHERE Word NOT IN ('', 'THE', 'A', 'AN', 'WHO', 'BOOK', 'AND', 'FOR', 'ON', 'HAVE', 'YOUR', 'HOW', 'WE', 'IN', 'I', 'IT', 'BY', 'SO', 'THEIR', 'IS', 'OR', 'HE', 'OF', 'WHAT'
, 'HIM', 'HIS', 'SHE', 'HER', 'MY', 'FROM', 'US', 'OUR', 'AT', 'ALL', 'BE', 'OF', 'TO', 'YOU', 'WITH', 'THAT', 'THIS', 'WAS', 'ARE', 'THERE', 'BUT', 'HAS'
, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 'WILL', 'MORE', 'DIV', 'THAN', 'EACH', 'GET', 'ANY')
AND LEN(Word) > 2
FETCH NEXT FROM db_cursor INTO #Value
END
CLOSE db_cursor
DEALLOCATE db_cursor
SELECT Word,COUNT(*)
FROM #WordList
GROUP BY Word

Get values after and before specific character in SQL/PL SQL?

I have a string value as a parameter and I need to parse it. My value is :
param := ('1234#5432#4567#8763');
I have to get 1234, 5432, 4567 and 8763 values partially. I will set these values different parameters.
How can I solve it with SQL?
Thanks,
select level, regexp_substr(a,'\d+',1,level)
from(select '1234#5432#4567#8763' a from dual)
connect by level <= regexp_count(a,'#') + 1
Assuming that you are in PL/SQL and you need to split a value of a parameter or a variable into four variables, this could be a way:
declare
param varchar2(100);
param1 varchar2(100);
param2 varchar2(100);
param3 varchar2(100);
param4 varchar2(100);
begin
param := '1234#5432#4567#8763';
--
param1 := substr(param, 1, instr(param, '#', 1, 1)-1);
param2 := substr(param, instr(param, '#', 1, 1) +1 , instr(param, '#', 1, 2) - instr(param, '#', 1, 1)-1);
param3 := substr(param, instr(param, '#', 1, 2) +1 , instr(param, '#', 1, 3) - instr(param, '#', 1, 2)-1);
param4 := substr(param, instr(param, '#', 1, 3) +1 );
--
dbms_output.put_line('Param1: ' || param1);
dbms_output.put_line('Param2: ' || param2);
dbms_output.put_line('Param3: ' || param3);
dbms_output.put_line('Param4: ' || param4);
end;
With regular expressions, you can get the same result by searching the 1st, 2nd, ... occurrence of a string that is followed by a # or by the end of the line ('$'); a better explanation of this approach is described in the link gave by Gary_W in his comment
...
param1 := regexp_substr(param, '(.*?)(#|$)', 1, 1, '', 1 );
param2 := regexp_substr(param, '(.*?)(#|$)', 1, 2, '', 1 );
param3 := regexp_substr(param, '(.*?)(#|$)', 1, 3, '', 1 );
param4 := regexp_substr(param, '(.*?)(#|$)', 1, 4, '', 1 );
...

Pandas HDFStore strange behaviour on shape

i am facing this strange behaviour, i got a HDFStore containing DataFrames.
For 2 keys in the store , shape information differs depending how they are query.
Example:
In [1]: mystore = pandas.HDFStore('/store')
In [2]: mystore
Out[2]:
<class 'pandas.io.pytables.HDFStore'>
File path: /store
/chunk_data frame (shape->[1,1])
/enrich_data_kb frame (shape->[1,11])
/inputs frame (shape->[105,4])
/prepare_data frame (shape->[105,7])
/reduce_data frame (shape->[18,4])
In [3]: mystore['chunk_data'].shape
Out[3]: (0, 1)
In [4]: mystore['enrich_data_kb'].shape
Out[4]: (18, 11)
In [5]: mystore['inputs'].shape
Out[5]: (105, 4)
Any Idea ?
As Jeff suggest, here is the result of ptdump (restricted to enrich_data_kb key):
/enrich_data_kb (Group) ''
/enrich_data_kb._v_attrs (AttributeSet), 13 attributes:
[CLASS := 'GROUP',
TITLE := '',
VERSION := '1.0',
axis0_variety := 'regular',
axis1_variety := 'regular',
block0_items_variety := 'regular',
block1_items_variety := 'regular',
block2_items_variety := 'regular',
encoding := None,
nblocks := 3,
ndim := 2,
pandas_type := 'frame',
pandas_version := '0.15.2']
/enrich_data_kb/axis0 (Array(11,)) ''
atom := StringAtom(itemsize=10, shape=(), dflt='')
maindim := 0
flavor := 'numpy'
byteorder := 'irrelevant'
chunkshape := None
/enrich_data_kb/axis0._v_attrs (AttributeSet), 7 attributes:
[CLASS := 'ARRAY',
FLAVOR := 'numpy',
TITLE := '',
VERSION := '2.4',
kind := 'string',
name := None,
transposed := True]
/enrich_data_kb/axis1 (Array(18,)) ''
atom := Int64Atom(shape=(), dflt=0)
maindim := 0
flavor := 'numpy'
byteorder := 'little'
chunkshape := None
/enrich_data_kb/axis1._v_attrs (AttributeSet), 7 attributes:
[CLASS := 'ARRAY',
FLAVOR := 'numpy',
TITLE := '',
VERSION := '2.4',
kind := 'integer',
name := None,
transposed := True]
/enrich_data_kb/block0_items (Array(8,)) ''
atom := StringAtom(itemsize=10, shape=(), dflt='')
maindim := 0
flavor := 'numpy'
byteorder := 'irrelevant'
chunkshape := None
/enrich_data_kb/block0_items._v_attrs (AttributeSet), 8 attributes:
[CLASS := 'ARRAY',
FLAVOR := 'numpy',
TITLE := '',
VERSION := '2.4',
freq := None,
kind := 'string',
name := None,
transposed := True]
/enrich_data_kb/block0_values (VLArray(1,)) ''
atom = ObjectAtom()
byteorder = 'irrelevant'
nrows = 1
flavor = 'numpy'
/enrich_data_kb/block0_values._v_attrs (AttributeSet), 5 attributes:
[CLASS := 'VLARRAY',
PSEUDOATOM := 'object',
TITLE := '',
VERSION := '1.4',
transposed := True]
/enrich_data_kb/block1_items (Array(2,)) ''
atom := StringAtom(itemsize=10, shape=(), dflt='')
maindim := 0
flavor := 'numpy'
byteorder := 'irrelevant'
chunkshape := None
/enrich_data_kb/block1_items._v_attrs (AttributeSet), 8 attributes:
[CLASS := 'ARRAY',
FLAVOR := 'numpy',
TITLE := '',
VERSION := '2.4',
freq := None,
kind := 'string',
name := None,
transposed := True]
/enrich_data_kb/block1_values (Array(18, 2)) ''
atom := Float64Atom(shape=(), dflt=0.0)
maindim := 0
flavor := 'numpy'
byteorder := 'little'
chunkshape := None
/enrich_data_kb/block1_values._v_attrs (AttributeSet), 5 attributes:
[CLASS := 'ARRAY',
FLAVOR := 'numpy',
TITLE := '',
VERSION := '2.4',
transposed := True]
/enrich_data_kb/block2_items (Array(1,)) ''
atom := StringAtom(itemsize=8, shape=(), dflt='')
maindim := 0
flavor := 'numpy'
byteorder := 'irrelevant'
chunkshape := None
/enrich_data_kb/block2_items._v_attrs (AttributeSet), 8 attributes:
[CLASS := 'ARRAY',
FLAVOR := 'numpy',
TITLE := '',
VERSION := '2.4',
freq := None,
kind := 'string',
name := None,
transposed := True]
/enrich_data_kb/block2_values (Array(18, 1)) ''
atom := Int64Atom(shape=(), dflt=0)
maindim := 0
flavor := 'numpy'
byteorder := 'little'
chunkshape := None
/enrich_data_kb/block2_values._v_attrs (AttributeSet), 5 attributes:
[CLASS := 'ARRAY',
FLAVOR := 'numpy',
TITLE := '',
VERSION := '2.4',
transposed := True]

Oracle PLSQL - Error handling in UTL_FILE

My script as below, it will load a csv file to PRODUCT_TBL and it any error happened during the process, the script will rollback transaction and output an error message, however it does not print out the message when it hit UTL_FILE error, example invalid file operations. Any help are appreciated. Thanks
DECLARE
V_error_code NUMBER;
V_error_message VARCHAR2(255);
V_ignore_headerlines NUMBER := 1;
V_eof BOOLEAN := FALSE;
F UTL_FILE.FILE_TYPE;
V_LINE VARCHAR2 (32767);
V_PRD_ID PRODUCT_TBL.PRD_ID%TYPE;
V_PATTERN PRODUCT_TBL.PATTERN%TYPE;
V_REMARK PRODUCT_TBL.REMARK%TYPE;
V_CREATED_BY PRODUCT_TBL.CREATED_BY%TYPE;
V_CREATED_DATE PRODUCT_TBL.CREATED_DATE%TYPE;
V_MODIFIED_BY PRODUCT_TBL.MODIFIED_BY%TYPE;
V_MODIFIED_DATE PRODUCT_TBL.MODIFIED_DATE%TYPE;
BEGIN
F := UTL_FILE.FOPEN ('DATA_DIR', 'PRODUCT_TBLv51.csv', 'R');
IF V_ignore_headerlines > 0
THEN
BEGIN
FOR i IN 1 .. V_ignore_headerlines
LOOP
UTL_FILE.get_line(F, V_LINE);
END LOOP;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
V_eof := TRUE;
END;
END IF;
WHILE NOT V_eof
LOOP
BEGIN
UTL_FILE.GET_LINE(F, V_LINE, 32767);
IF V_LINE IS NULL THEN
EXIT;
END IF;
V_PRD_ID := REGEXP_SUBSTR(V_LINE, '([^,\(]*(\([^\)]*\)[^,\(]*)*)(,|$)', 1, 1, 'i', 1);
V_PATTERN := REGEXP_SUBSTR(V_LINE, '([^,\(]*(\([^\)]*\)[^,\(]*)*)(,|$)', 1, 2, 'i', 1);
V_REMARK := REGEXP_SUBSTR(V_LINE, '([^,\(]*(\([^\)]*\)[^,\(]*)*)(,|$)', 1, 12, 'i', 1);
V_CREATED_BY := REGEXP_SUBSTR(V_LINE, '([^,\(]*(\([^\)]*\)[^,\(]*)*)(,|$)', 1, 13, 'i', 1);
V_CREATED_DATE := REGEXP_SUBSTR(V_LINE, '([^,\(]*(\([^\)]*\)[^,\(]*)*)(,|$)', 1, 14, 'i', 1);
V_MODIFIED_BY := REGEXP_SUBSTR(V_LINE, '([^,\(]*(\([^\)]*\)[^,\(]*)*)(,|$)', 1, 15, 'i', 1);
V_MODIFIED_DATE := REGEXP_SUBSTR(V_LINE, '([^,\(]*(\([^\)]*\)[^,\(]*)*)(,|$)', 1, 16, 'i', 1);
INSERT INTO PRODUCT_TBL (PRD_ID,PATTERN,REMARK,CREATED_BY,CREATED_DATE,MODIFIED_BY,MODIFIED_DATE)
VALUES(V_PRD_ID, V_PATTERN, V_REMARK, V_CREATED_BY, V_CREATED_DATE, V_MODIFIED_BY, V_MODIFIED_DATE);
EXCEPTION
WHEN OTHERS THEN
ROLLBACK;
v_error_code := SQLCODE;
v_error_message := SQLERRM;
dbms_output.put_line(v_error_code || SQLERRM);
EXIT;
END;
END LOOP;
COMMIT;
UTL_FILE.FCLOSE(F);
EXCEPTION
WHEN UTL_FILE.INVALID_OPERATION THEN
UTL_FILE.FCLOSE(F);
dbms_output.put_line('File could not be opened or operated on as requested.');
END;
/
add an EXCEPTION ... OTHER Block after the UTL_FILE part and see what kind of Exceptions actually go throuhg to catch them.
EXCEPTION
WHEN UTL_FILE.INVALID_OPERATION THEN
UTL_FILE.FCLOSE(F);
dbms_output.put_line('File could not be opened or operated on as requested.');
WHEN OTHERS THEN
dbms_output.put_line('other trouble'||SQLCODE||SQLERRM);
When you know which one happened you will know how to catch it.