How to append a word to a line in a file without moving to next line -? - sql

I am using UTL_FILE to extract output from the .csv file and trying to append the gender to the already existing file data. But in everyway I tried I am unable to get the expected output. Need quick help on this.
Actual File (Details.csv):
Name,Country,State,City
Lina,Brazil,Bahia,Salvador
John,USA,Texas,Austin
Ashton,Australia,Tasmania,Hobart
My output:
Name,Country,State,City
,Gender
Lina,Brazil,Bahia,Salvador
,Female
John,USA,Texas,Austin
,Male
Ashton,Australia,Tasmania,Hobart
,Male
Expected Output (Details_upd.csv):
Name,Country,State,City,Gender
Lina,Brazil,Bahia,Salvador,Female
John,USA,Texas,Austin,Male
Ashton,Australia,Tasmania,Hobart,Male
------Code--------
DECLARE
f_line VARCHAR2 (32767);
file_1 UTL_FILE.file_type;
file_2 UTL_FILE.file_type;
f_dir VARCHAR2 (25) := 'DATA';
L_check_UPDATED BOOLEAN;
l_line VARCHAR2(32767);
BEGIN
file_1 := UTL_FILE.fopen (f_dir,'Details.csv','R');
file_2 := UTL_FILE.fopen (f_dir,'Details_upd.csv', 'W');
UTL_FILE.get_line (file_1, f_line);
l_line := trim(f_line);
UTL_FILE.PUT_LINE(file_2,l_line||','||'Gender');
LOOP
L_check_UPDATED := TRUE;
/*--omitting the LOGIC part of code--*/
IF (L_check_UPDATED) THEN
l_line := trim(f_line);
UTL_FILE.PUT(file_2,l_line||',Male');
ELSE
l_line := trim(f_line);
UTL_FILE.PUT_LINE(file_2,l_line||',Female');
END IF;
END LOOP;
UTL_FILE.fclose (file_1);
UTL_FILE.fclose (file_2);
END;

You will need to strip off the new-line character at the end of the string that you have read using GET_LINE. Try:
l_line := rtrim (f_line, ' ' || CHR (10) || CHR (13))

Most likely your oracle is unix (line terminator character is chr(10)) and your file is binary transferred windows (line terminator chr(13)+chr(10))
And after utl_file read chr(13) is left over. You can use dump function to analyze the contents of the buffer.

Related

HOW TO ADD HEADER AND FOOTER AT THE OF THE CODE TO GET THE REQUIRED O/P

Write a procedure to genearte a report of all employee with managers name details with | (pipe delimiter) in unix development server /tmp path.
Example:**
Emp ID|Emp Name|Manager Name|Sal|Dept No|Location -------header**
7369|SMITH|FORD|800|20|DALLAS
Total Record|1 ------Trailer
f_handle2 utl_file.file_type;
begin
f_handle2 := utl_file.fopen(
'TESTING_DIR' -- File location
, 'EMP_DET_WITH_MANA_NAME2' -- File name
, 'w'); -- Open mode: w = write.
for i in (select empno,ename,manager_name,sal,deptno,loc,count(empno) from t77)
loop
utl_file.putf(f_handle2,i.empno||'|'||i.ename||'|'||i.manager_name||'|'||i.sal||'|'||i.deptno||'"'||i.loc);
UTL_FILE.NEW_LINE(f_handle2);
end loop;
utl_file.fclose(f_handle2);
exception
when others then
dbms_output.put_line('ERROR: ' || SQLCODE || ' - ' || SQLERRM);
raise;
end;

long raw to pdf

good afternoon,
I am in need of help to read a field in the Oracle database.
I have a long raw field that contains a pdf and I need to save it to a file.
Does anyone have any suggestions on how I can do it?
If you have access to Oracle Support, there is an example in Doc ID 1433573.1
Sample Procedure
CREATE OR REPLACE PROCEDURE WritePDFToFILE (myfilename IN VARCHAR2)
IS
v_blob BLOB;
blob_length INTEGER;
out_file UTL_FILE.FILE_TYPE;
-- chunk size and buffer size must match
chunk_size BINARY_INTEGER := 32767;
v_buffer RAW (32767);
blob_position INTEGER := 1;
BEGIN
-- Retrieve the BLOB for reading
SELECT filedata
INTO v_blob
FROM blob_pdf_tbl
WHERE filename = myfilename;
-- Retrieve the SIZE of the BLOB
blob_length := DBMS_LOB.GETLENGTH (v_blob);
-- Open a handle to the location where you are going to write the BLOB to a file
-- NOTE: The 'wb' parameter means "write in byte mode" and is only availabe
-- in the UTL_FILE package with Oracle 10g or later
out_file :=
UTL_FILE.FOPEN ('PDF_DIR_LOC',
myfilename,
'wb',
chunk_size);
-- Write the BLOB to file in chunks
WHILE blob_position <= blob_length
LOOP
IF blob_position + chunk_size - 1 > blob_length
THEN
chunk_size := blob_length - blob_position + 1;
END IF;
DBMS_LOB.READ (v_blob,
chunk_size,
blob_position,
v_buffer);
UTL_FILE.PUT_RAW (out_file, v_buffer, TRUE);
blob_position := blob_position + chunk_size;
END LOOP;
-- Close the file handle
UTL_FILE.FCLOSE (out_file);
END;
/

How to Write Blob from Oracle Column to the File System

my_images table consists of a blob column called images. I need to write these images to my image_dir which is 'C:\TEMP'.
When the following PL/SQL code is executed, only the first image is written to the directory as an image. The second blob is written as 0 byte (empty) and there is no other (Should be a total number of 8).
So the loop does not seem to work correctly. I am using Oracle 11g Express Edition (XE) and SQL Developer. Here is the error and the code:
Error starting at line : 53 in command -
BEGIN write_blob_to_file_v5; END;
Error report -
ORA-01403: no data found
ORA-06512: at "SYS.DBMS_LOB", line 1056
ORA-06512: at "SYS.WRITE_BLOB_TO_FILE_V5", line 40
ORA-06512: at line 1
01403. 00000 - "no data found"
*Cause: No data was found from the objects.
*Action: There was no data from the objects which may be due to end of fetch.
PL/SQL code
CREATE OR REPLACE PROCEDURE write_blob_to_file_v5
AS
v_lob_image_name VARCHAR (100);
v_lob_image_id NUMBER;
v_blob BLOB;
v_buffer RAW (32767);
v_buffer_size BINARY_INTEGER;
v_amount BINARY_INTEGER;
v_offset NUMBER (38) := 1;
v_chunksize INTEGER;
v_out_file UTL_FILE.file_type;
BEGIN
FOR i IN (SELECT DBMS_LOB.getlength (v_blob) v_len,
image_id v_lob_image_id,
"IMAGE_NAME" v_lob_image_name,
image v_blob
FROM sys.MY_IMAGES)
LOOP
v_chunksize := DBMS_LOB.getchunksize (i.v_blob);
IF (v_chunksize < 32767)
THEN
v_buffer_size := v_chunksize;
ELSE
v_buffer_size := 32767;
END IF;
v_amount := v_buffer_size;
DBMS_LOB.open (i.v_blob, DBMS_LOB.lob_readonly);
v_out_file :=
UTL_FILE.fopen (
location => 'IMAGE_DIR',
filename => ( ''
|| i.v_lob_image_id
|| '_'
|| i.v_lob_image_name
|| '.JPG'),
open_mode => 'wb',
max_linesize => 32767);
WHILE v_amount >= v_buffer_size
LOOP
DBMS_LOB.read (i.v_blob,
v_amount,
v_offset,
v_buffer);
v_offset := v_offset + v_amount;
UTL_FILE.put_raw (file => v_out_file,
buffer => v_buffer,
autoflush => TRUE);
UTL_FILE.fflush (file => v_out_file);
--utl_file.new_line(file => v_out_file);
END LOOP;
UTL_FILE.fflush (v_out_file);
UTL_FILE.fclose (v_out_file);
DBMS_LOB.close (i.v_blob);
END LOOP;
END;
The main problem is related NOT to re-initialize the parameter v_offset to 1 ( as in the declaration section ) :
v_offset := 1;
for every image id just before
v_chunksize := dbms_lob.getchunksize(i.v_blob);
assignment.
Moreover, the problem may arise about not yet closed or already opened blobs. To prevent these,
replace
dbms_lob.open(i.v_blob,dbms_lob.lob_readonly);
with
if ( dbms_lob.isopen(i.v_blob)=0 ) then
dbms_lob.open(i.v_blob,dbms_lob.lob_readonly);
end if;
and
replace
dbms_lob.close(i.v_blob);
with
if ( dbms_lob.isopen(i.v_blob)=1 ) then
dbms_lob.close(i.v_blob);
end if;

plsql reading text file in an array

When I run this portion of my code, which is inside a package, I get an error (specifically at the l_cnt := 1_cnt + 1 line for some reason and the code crashes. What could I be doing wrong? I am trying to read in a file of certs. Here's what I have so far:
v_certList arr_claims_t := arr_claims_t();
v_certLst VARCHAR2(2000);
f UTL_FILE.FILE_TYPE;
s VARCHAR2(200);
-- used for looping
l_cnt simple_integer := 0;
/*cop procedure*/
PROCEDURE COP_DATALOAD_V2 AS
arr_claims arr_claims_t;
arr_sql arr_sql_t;
BEGIN
f := UTL_FILE.FOPEN('V_COP',
'certs_file.txt',
'R',
2500);
-- populata our v_certlist of arr_claims_t
loop
utl_file.get_line(f, s);
v_certList.extend();
l_cnt := l_cnt+1;
v_certList(l_cnt) := s;
end loop;
exception
when no_data_found then
utl_file.fclose(f);
I want the array to be succesfuly populated given a text file (and I understand this is not the best practice but this is what I will have to do for now)
I figured out the error! The s that it was reading in was too big for the array. This was because empty spaces in the files was included.
v_certList.extend(1);
l_cnt := l_cnt + 1;
v_certList(l_cnt) := substr(s,
0,
10)
This fixed it for me.

Oracle SQL: Find {tags} in a sql string

I have SQL strings that my users write. They look like:
SELECT Name, Age from Users WHERE Name LIKE '%a%' AND {UsersWhere}
On the oracle server side when such an SQL is to be executed I want to replace the {tags} first. The replacements for the {tags} will be valid SQL sub strings I am holding in a table. Pre-manufactered sub sqls. So the treated string will be valid SQL.
Is there some fancy build-in Oracle function to make this happen?
Thanks for a hint!
I have written a small function for anyone interested:
CREATE OR REPLACE FUNCTION SA.REPLACE_VARIABLES (p_sql IN VARCHAR2)
RETURN VARCHAR2
IS
vs_return VARCHAR2 (4000);
-- Deklarationen
vs_sql VARCHAR2(4000);
vs_substring VARCHAR2(4000);
vs_variable VARCHAR2(200);
vs_variable_content VARCHAR2(4000);
BEGIN
vs_sql := p_sql;
IF INSTR(p_sql, '{') > 0 THEN
vs_substring := vs_sql;
WHILE LENGTH(vs_substring) > 0 LOOP
IF INSTR(vs_substring, '{') <> 0
THEN
vs_variable := SUBSTR(vs_substring, INSTR(vs_substring, '{'), INSTR(vs_substring, '}') - INSTR(vs_substring, '{') + 1);
-- Do whatever you want with the variable
--vs_sql := REPLACE(vs_sql, vs_variable, vs_variable_content);
-- Substring verkürzen
vs_substring := SUBSTR(vs_substring, INSTR(vs_substring, vs_variable) + LENGTH(vs_variable) + 1);
ELSE
vs_substring := '';
END IF;
END LOOP;
END IF;
RETURN vs_sql;
EXCEPTION
WHEN OTHERS
THEN
-- Err -handle
END REPLACE_VARIABLES;
/
I'd just keep it simple:
v_sql := REPLACE(v_sql, '{UsersWhere}', '...whatever you need...');