I have been working on this for days. I need help on Spanish data export from DB instance. I'm trying to query table data and export into oracle Directory (Example:outbound) but I see Spanish accent characters are getting stripped off. I use UTL_FILE package to export data into oracle directory. Below are the database characterset:
NLS_CHARACTERSET :US7ASCII NLS_NCHAR_CHARACTERSET:AL16UTF16
Tablename: sp_table1 Column_name: Sp_description nvarchar2(2000);
CREATE OR REPLACE PROCEDURE run_query(p_sql IN VARCHAR2
,p_dir IN VARCHAR2
,p_file IN VARCHAR2
) IS
v_finaltxt VARCHAR2(4000);
v_v_val VARCHAR2(4000);
v_n_val NUMBER;
v_d_val DATE;
v_ret NUMBER;
c NUMBER;
d NUMBER;
col_cnt INTEGER;
f BOOLEAN;
rec_tab DBMS_SQL.DESC_TAB;
col_num NUMBER;
v_fh UTL_FILE.FILE_TYPE;
v_delimiter VARCHAR2(1):='|';
BEGIN
c := DBMS_SQL.OPEN_CURSOR;
DBMS_SQL.PARSE(c, p_sql, DBMS_SQL.NATIVE);
d := DBMS_SQL.EXECUTE(c);
DBMS_SQL.DESCRIBE_COLUMNS(c, col_cnt, rec_tab);
FOR j in 1..col_cnt
LOOP
CASE rec_tab(j).col_type
WHEN 1 THEN DBMS_SQL.DEFINE_COLUMN(c,j,v_v_val,2000);
WHEN 2 THEN DBMS_SQL.DEFINE_COLUMN(c,j,v_n_val);
WHEN 12 THEN DBMS_SQL.DEFINE_COLUMN(c,j,v_d_val);
ELSE
DBMS_SQL.DEFINE_COLUMN(c,j,v_v_val,2000);
END CASE;
END LOOP;
-- This part outputs the HEADER
v_fh := UTL_FILE.FOPEN(upper(p_dir),p_file,'w',32767);
FOR j in 1..col_cnt
LOOP
--v_finaltxt := ltrim(v_finaltxt||','||lower(rec_tab(j).col_name),',');
v_finaltxt := ltrim(v_finaltxt||v_delimiter||InitCap(rec_tab(j).col_name),v_delimiter); --Pipe
END LOOP;
UTL_FILE.PUT_LINE(v_fh, v_finaltxt);
-- This part outputs the DATA
LOOP
v_ret := DBMS_SQL.FETCH_ROWS(c);
EXIT WHEN v_ret = 0;
v_finaltxt := NULL;
FOR j in 1..col_cnt
LOOP
CASE rec_tab(j).col_type
WHEN 1 THEN DBMS_SQL.COLUMN_VALUE(c,j,v_v_val);
--v_finaltxt := ltrim(v_finaltxt||',"'||v_v_val||'"',',');
v_finaltxt := ltrim(v_finaltxt||v_delimiter||v_v_val||'',v_delimiter);
WHEN 2 THEN DBMS_SQL.COLUMN_VALUE(c,j,v_n_val);
--v_finaltxt := ltrim(v_finaltxt||','||v_n_val,',');
v_finaltxt := ltrim(v_finaltxt||v_delimiter||v_n_val,v_delimiter);
WHEN 12 THEN DBMS_SQL.COLUMN_VALUE(c,j,v_d_val);
--v_finaltxt := ltrim(v_finaltxt||','||to_char(v_d_val,'DD/MM/YYYY HH24:MI:SS'),',');
v_finaltxt := ltrim(v_finaltxt||v_delimiter||to_char(v_d_val,'YYYYMMDD'),v_delimiter);
ELSE
DBMS_SQL.COLUMN_VALUE(c,j,v_v_val);
--v_finaltxt := ltrim(v_finaltxt||',"'||v_v_val||'"',v_delimiter);
v_finaltxt := ltrim(v_finaltxt||v_delimiter||v_v_val||'',v_delimiter);
END CASE;
END LOOP;
-- DBMS_OUTPUT.PUT_LINE(v_finaltxt);
UTL_FILE.PUT_LINE(v_fh, v_finaltxt);
END LOOP;
UTL_FILE.FCLOSE(v_fh);
DBMS_SQL.CLOSE_CURSOR(c);
EXCEPTION
WHEN UTL_FILE.INVALID_PATH THEN
UTL_FILE.FCLOSE(v_fh);
RAISE_APPLICATION_ERROR(-20000, 'File location is invalid.');
WHEN UTL_FILE.INVALID_MODE THEN
UTL_FILE.FCLOSE(v_fh);
RAISE_APPLICATION_ERROR(-20001, 'The open_mode parameter in FOPEN is invalid.');
WHEN UTL_FILE.INVALID_FILEHANDLE THEN
UTL_FILE.FCLOSE(v_fh);
RAISE_APPLICATION_ERROR(-20002, 'File handle is invalid.');
WHEN UTL_FILE.INVALID_OPERATION THEN
UTL_FILE.FCLOSE(v_fh);
RAISE_APPLICATION_ERROR(-20003, 'File could not be opened or operated on as requested.');
WHEN UTL_FILE.READ_ERROR THEN
UTL_FILE.FCLOSE(v_fh);
RAISE_APPLICATION_ERROR(-20004, 'Operating system error occurred during the read operation.');
WHEN UTL_FILE.WRITE_ERROR THEN
UTL_FILE.FCLOSE(v_fh);
RAISE_APPLICATION_ERROR(-20005, 'Operating system error occurred during the write operation.');
WHEN UTL_FILE.INTERNAL_ERROR THEN
UTL_FILE.FCLOSE(v_fh);
RAISE_APPLICATION_ERROR(-20006, 'Unspecified PL/SQL error.');
WHEN UTL_FILE.CHARSETMISMATCH THEN
UTL_FILE.FCLOSE(v_fh);
RAISE_APPLICATION_ERROR(-20007, 'A file is opened using FOPEN_NCHAR, but later I/O ' ||
'operations use nonchar functions such as PUTF or GET_LINE.');
WHEN UTL_FILE.FILE_OPEN THEN
UTL_FILE.FCLOSE(v_fh);
RAISE_APPLICATION_ERROR(-20008, 'The requested operation failed because the file is open.');
WHEN UTL_FILE.INVALID_MAXLINESIZE THEN
UTL_FILE.FCLOSE(v_fh);
RAISE_APPLICATION_ERROR(-20009, 'The MAX_LINESIZE value for FOPEN() is invalid; it should ' ||
'be within the range 1 to 32767.');
WHEN UTL_FILE.INVALID_FILENAME THEN
UTL_FILE.FCLOSE(v_fh);
RAISE_APPLICATION_ERROR(-20010, 'The filename parameter is invalid.');
WHEN UTL_FILE.ACCESS_DENIED THEN
UTL_FILE.FCLOSE(v_fh);
RAISE_APPLICATION_ERROR(-20011, 'Permission to access to the file location is denied.');
WHEN UTL_FILE.INVALID_OFFSET THEN
UTL_FILE.FCLOSE(v_fh);
RAISE_APPLICATION_ERROR(-20012, 'The ABSOLUTE_OFFSET parameter for FSEEK() is invalid; ' ||
'it should be greater than 0 and less than the total ' ||
'number of bytes in the file.');
WHEN UTL_FILE.DELETE_FAILED THEN
UTL_FILE.FCLOSE(v_fh);
RAISE_APPLICATION_ERROR(-20013, 'The requested file delete operation failed.');
WHEN UTL_FILE.RENAME_FAILED THEN
UTL_FILE.FCLOSE(v_fh);
RAISE_APPLICATION_ERROR(-20014, 'The requested file rename operation failed.');
WHEN OTHERS THEN
UTL_FILE.FCLOSE(v_fh);
RAISE;
END;
/
Expected : Servicio de transporte m é dico Actual: Servicio de transporte medico
A couple of suggestions.
First, your NLS_CHARACTERSET is set to US7ASCII so any time you use a VARCHAR2 variable or value you're going to lose your accented characters.
On the bright side your NLS_NCHAR_CHARACTERSET is set to AL16UTF16, so NVARCHAR2 values should preserve your accented characters.
Because you're using DBMS_SQL it's difficult to tell what columns you're fetching, but I'll guess that one of them is SP_TABLE1.SP_DESCRIPTION
which you say is defined as NVARCHAR2(2000)
. It appears, however, that you're fetching that into a variable defined as VARCHAR2
since there are no variables defined as NVARCHAR2
in your procedure. Oracle is happy to do this for you, making the necessary conversion, but you're going to lose your accented characters in the process. You're going to need to fetch this column into a variable defined as NVARCHAR2
.
Then, when writing this value out you'll need to use the UTL_FILE.PUT_LINE_NCHAR
procedure, rather than UTL_FILE.PUT_LINE
. The former takes an NVARCHAR2
parameter, and should preserve your accented characters.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.