error in coverting a clob data to varchar2 - oracle

I tried to convert a clob datatype to varchar2 datatype using the dbms_lob command, but im getting error as shown below
ERROR:
ORA-06502: PL/SQL: numeric or value error: character string buffer too small
table structure:
desc test_default_settings
Name Null Type
------------- ---- -------------
DEFAULT_KEY VARCHAR2(100)
DEFAULT_VALUE CLOB
Table Content:
Default_key Default_Value
====================== ==================
EMAIL_TEMPLATE_NAME Invitation Email Template
EMAIL_TEMPLATE_FROM admin#xxx.com
EMAIL_TEMPLATE_SUBJECT Welcome to test company!!!
EMAIL_TEMPLATE_EXP_DAYS 2
EMAIL_TEMPLATE_MSG <html><p>Dear {First_Name}, {Last_Name}<span id="selectionBoundary_1496237162220_4685507087412435" class="rangySelectionBoundary"></span></p><p>...
..................</html>
Since the value of the EMAIL_TEMPLATE_MSG is too long to display, for reference I have marked as "...."
query used :
SELECT e.default_key,
TO_CHAR(DBMS_LOB.SUBSTR(e.default_value,5000, 1)) AS DEFAULT_VALUE
FROM test_default_settings e;
Note:
I can extact all the contents of data , except for EMAIL_TEMPLATE_MSG data
eg:
SELECT e.default_key,
TO_CHAR(DBMS_LOB.SUBSTR(e.default_value,5000, 1)) AS DEFAULT_VALUE
FROM test_default_settings e where default_key= 'EMAIL_TEMPLATE_NAME';
DEFAULT_KEY DEFAULT_VALUE
-------------- ----------------
EMAIL_TEMPLATE_NAME Invitation Email Template
but when i do the same to extract the html content, im getting error
SELECT e.default_key,
TO_CHAR(DBMS_LOB.SUBSTR(e.default_value,5000, 1)) AS DEFAULT_VALUE
FROM test_default_settings e where default_key= 'EMAIL_TEMPLATE_MSG';
output:
ORA-06502: PL/SQL: numeric or value error: character string buffer too small
ORA-06512: at line 1
when i tried to increase the value of dbms_lob parameter to 80000, im getting the value as null.
Can you please help

DBMS_LOB.SUBSTR and SUBSTR work different. DBMS_LOB.SUBSTR(amount,offset) , SUBSTR(offset,amount).
Example
select DBMS_LOB.SUBSTR('1234567890',5,1),substr('1234567890',5,1),
DBMS_LOB.SUBSTR('1234567890',1,5)
from dw_mailing;
In your query dbms_lob.SUBSTR for long CLOB is extracting 5000 bytes and try to convert this byte to varchar2. But varchar2 max size in sql is 4000.

Related

Error in executing a control file in SQL Loader

This here is my data file Sample1.dat
10013010-05-202212-05-202217-05-2022Not WellS5 A
10113111-04-202112-04-202112-04-2022Fever A365P
10213201-07-202203-07-202206-07-2022VacationC5 R
10313301-03-202201-03-202207-03-2022Not wellS6 A
10413415-02-202216-02-202218-02-2022HospitalS2 P
This is my control file Controlfile1.ctl
LOAD DATA
INFILE 'Sample1.dat'
APPEND INTO TABLE EMP_LEAVE(
REQUEST_NO POSITION(01:03) NUMBER,
EMPNO POSITION(04:06) NUMBER,
REQUEST_DATE POSITION(07:16) DATE "DD-MON-YYY",
START_DATE POSITION(17:26) DATE "DD-MON-YYY",
END_DATE POSITION(27:36) DATE "DD-MON-YYY",
REASON POSITION(37:44) VARCHAR2,
LEAVE_TYPE POSITION(45:45) CHAR,
NO_OF_DAYS POSITION(46:48) NUMBER,
APPROVAL POSITION(49:49) CHAR
)
When I try to call it in sql loader, I get the following error
SQL*Loader-350: Syntax error at line 4.
Expecting valid column specification, "," or ")", found "NUMBER".
REQUEST_NO POSITION(01:03) NUMBER,
Can someone help me out?

Convert and compare a field datatype in Oracle

I have a Varchar2 field named Contract_Value and its values are as follows,
Contract_Value
---------------
USD 300,000
EUR 120,215.65
AUD 237,176.39
JPY 31,284.32
Now I need do a validation to this field for a dashboard application as follows,
SELECT COUNT(*), VALUE FROM
(SELECT CASE WHEN REGEXP_REPLACE(A.CONTRACT_VALUE, '[^.0-9]') > 100
THEN 'P' ELSE 'F' END AS VALUE FROM DOCUMENTS A)
GROUP BY VALUE;
But its throwing an error that INVALID NUMBER
The reason is given the CONTRACT_VALUE field is VARCHAR2 as mentioned above and my validation is with Number which is > 100
I tried to use CAST and TO_NUMBER keywords to change the Data type from VARCHAR2 to NUMBER but still no luck.

Oracle user defined records

In Oracle PL/SQL records we can use anchor datatypes (including %TYPE and %ROWTYPE) to define the fields.
When I populate a record from a query, in my select clause I want type conversion. Is that possible using an Oracle built-in function or some other approach?
In this example scenario I am using a simple decode function to perform a conversion:
DECLARE
TYPE TEST_RECORD IS RECORD(
FIRST_NAME EMPLOYEE_MT.FIRST_NAME%TYPE,
LAST_NAME EMPLOYEE_MT.LAST_NAME%TYPE,
MARITIAL_STATUS EMPLOYEE_MT.MARITAL_STATUS%TYPE);
EMPLOYEE_NAME TEST_RECORD;
BEGIN
SELECT EMP.FIRST_NAME,
EMP.LAST_NAME,
DECODE(EMP.MARITAL_STATUS, 1, 'MARRIED', 0, 'UN-MARRIED')
INTO EMPLOYEE_NAME
FROM EMPLOYEE_MT EMP
WHERE EMP.EMPLOYEE_ID = 1;
DBMS_OUTPUT.put_line(EMPLOYEE_NAME.MARITIAL_STATUS);
END;
which gets error:
ORA-06502: PL/SQL: numeric or value error: character to number conversion error
ORA-06512: at line 9
You have defined your record type with the maritial_status (shouldn't that be marital_status?) field using the same data type as the table column. From your decode that appears to be a number data type. You're then trying to set the record's field value to a string, either 'MARRIED' or 'UN-MARRIED', when that field is expecting a number. Clearly neither of those strings can be converted to a number, hence the error you're getting.
If you want the record to store the string value, you'll have to define it like that - explicitly as a string, rather than using %TYPE:
DECLARE
TYPE TEST_RECORD IS RECORD(
FIRST_NAME EMPLOYEE_MT.FIRST_NAME%TYPE,
LAST_NAME EMPLOYEE_MT.LAST_NAME%TYPE,
MARITAL_STATUS VARCHAR2(10));
...
DBMS_OUTPUT.put_line(EMPLOYEE_NAME.MARITAL_STATUS);
...
You can't do that automatically using %TYPE as the data type just doesn't match. You've explicitly told Oracle that you want the field's data type to be a number, so Oracle isn't going to let you put a string in that field instead. It isn't about there not being a built-in function, it just doesn't make sense.
This also means you can't use %ROWTYPE if you're changing the data type either (unless your modified value can be implicitly converted back to the column data type).

Oracle SQL sqlldr not importing a latitude/longitude as float

I am trying to import some data with sql*loader but I can't import a latitude/longitude. On the table those columns are FLOAT(126) and on the data file is just text. I tried with FLOAT EXTERNAL on the sqlldr control file but it doesn't work. I got ORA-01722: invalid number.
Describe my_table;
Name Null Type
------------------------- -------- ------------
PRE_ID NOT NULL NUMBER(38)
PRE_DH NOT NULL TIMESTAMP(6)
PRE_PRO NOT NULL NUMBER(38)
PRE_INF NOT NULL NUMBER(38)
PRE_TPL NOT NULL NUMBER(38)
PRE_LAT NOT NULL FLOAT(126)
PRE_LNG NOT NULL FLOAT(126)
data file:
55831;08/12/2016 16:48:07;1;-128;2;-22.4741249084473;-50.55194854736336
55831;09/12/2016 08:02:06;1;-128;2;-22.5002975463867;-50.8194427490234
55831;09/12/2016 19:12:06;1;-128;2;-22.5002975463867;-50.8194427490234
and sqlldr control file:
load data
infile 'my_file.csv' "str '\r\n'"
append
into table my_table
fields terminated by ';'
trailing nullcols
( PRE_ID CHAR(4000),
PRE_DH TIMESTAMP "DD/MM/YYYY HH24:MI:SS",
PRE_PRO CHAR(4000),
PRE_INF CHAR(4000),
PRE_TPL CHAR(4000),
PRE_LAT FLOAT EXTERNAL,
PRE_LNG FLOAT EXTERNAL,
)
log file:
Table MY_TABLE, loaded from every logical record.
Insert option in effect for this table: APPEND
TRAILING NULLCOLS option in effect
Column Name Position Len Term Encl Datatype
------------------------------ ---------- ----- ---- ---- ---------------------
PRE_ID FIRST 4000 ; CHARACTER
PRE_DH NEXT * ; DATETIME DD/MM/YYYY HH24:MI:SS
PRE_PRO NEXT 4000 ; CHARACTER
PRE_INF NEXT 4000 ; CHARACTER
PRE_TPL NEXT 4000 ; CHARACTER
PRE_LAT NEXT * ; CHARACTER
PRE_LNG NEXT * ; CHARACTER
value used for ROWS parameter changed from 64 to 1
Record 1: Rejected - Error on table MY_TABLE, column PRE_LAT.
ORA-01722: invalid number
Record 2: Rejected - Error on table MY_TABLE, column PRE_LAT.
ORA-01722: invalid number
Record 3: Rejected - Error on table MY_TABLE, column PRE_LAT.
ORA-01722: invalid number
You're seeing this because the operating system environment is set up in a way that causes Oracle to treat a comma as a decimal separator and a period as a group separator. Your error messages are in English, interestingly, so not sure exactly what you have that set to, but you can see the same thing with something like NLS_LANG="FRENCH_FRANCE.WE8ISO8859P1".
From the log you can see that the field in your CSV file is being read as character data. The target column is a float (any type of number column would have the same issue), which means an implicit conversion is happening, and is using your NLS settings. You can see the same thing more simply with:
alter session set NLS_NUMERIC_CHARACTERS='.,';
select to_number('-22.4741249084473') from dual;
TO_NUMBER('-22.4741249084473')
------------------------------
-22.4741249084473
alter session set NLS_NUMERIC_CHARACTERS=',.';
select to_number('-22.4741249084473') from dual;
Error report -
ORA-01722: invalid number
Same conversion, but the alter session is swapping the meaning of the comma and period.
You can either explicitly set your environment to something with the right NLS numeric characters via NLS_LANG:
export NLS_LANG="ENGLISH_UNITED KINGDOM.WE8ISO8859P1"
or just that specific setting:
export NLS_NUMERIC_CHARACTERS='.,'
... before running SQL*Loader.

Problem with Oracle Sql Loader control file

I'm trying to load some data using sql loader. Here is the top of my control/data file:
LOAD DATA
INFILE *
APPEND INTO TABLE economic_indicators
FIELDS TERMINATED BY ','
(ASOF_DATE DATE 'DD-MON-YY',
VALUE FLOAT EXTERNAL,
STATE,
SERIES_ID INTEGER EXTERNAL,
CREATE_DATE DATE 'DD-MON-YYYY')
BEGINDATA
01-Jan-79,AL,67.39940538,1,23-Jun-2009
... lots of other data lines.
The problem is that sql loader won't recognize the data types I'm specifying. This is the log file:
Table ECONOMIC_INDICATORS, loaded from every logical record.
Insert option in effect for this table: APPEND
Column Name Position Len Term Encl Datatype
------------------------------ ---------- ----- ---- ---- ---------------------
ASOF_DATE FIRST * , DATE DD-MON-YY
VALUE NEXT * , CHARACTER
STATE NEXT * , CHARACTER
SERIES_ID NEXT * , CHARACTER
CREATE_DATE NEXT * , DATE DD-MON-YYYY
value used for ROWS parameter changed from 10000 to 198
Record 1: Rejected - Error on table ECONOMIC_INDICATORS, column VALUE.
ORA-01722: invalid number
... lots of similiar errors, expected if trying to insert char data into a numeric column.
I've tried no datatype spec, all other numeric specs, and always the same issue. Any ideas?
Also, any ideas on why it's changing the Rows parameter?
From your example, SQL*Loader will try to evaluate the string "AL" to a number value, which will result in the error message you gave. The sample data has something looking like it could be a decimal number at third position, not second as specified int he column list.

Resources