Casting error oracle - oracle

I have tried both[CAST & TO_NUMBER] method but non of worked to cast values that is returned from another procedure.
SELECT DBMS_LOB.SUBSTR(SUBSTR(DETAIL_LOB, 2300, 4), 2000)
INTO RES
FROM lONG_TO_CLOB_TEMP_TABLE;`
RES VALUE IS 40 returned by above query.
RES datatype is varchar2.
Now I want to convert that RES value into number so that I can do some arithmetic operation with this.
like => 100/RES
Not working code =>
V_TEMP := CAST(RES AS NUMBER)
V_TEMP := TO_NUMBER(RES)
Error Message => "ORA-06502: PL/SQL: numeric or value error"

Its most likely special character involve in (space or line break)
Try
V_TEM := To_number(regexp_replace(trim(RES), '(^[[:space:]]+)|([[:space:]]+$)',null))

There was a line break causing the problem.
Solved with:-
REPLACE(REPLACE(REPLACE(column_name, CHR(10)), CHR(13)), CHR(9));
--Special thanks to #KaushikNayak

In order to remove a newline character using PL/SQL, use the following:
declare charwithnewline VARCHAR2(10) := CONCAT('190', CHR(13));
begin
dbms_output.put_line('+++++++++++++++++++++++++');
dbms_output.put_line(charwithnewline);
dbms_output.put_line('+++++++++++++++++++++++++');
dbms_output.put_line(REPLACE(charwithnewline,CHR(13),''));
dbms_output.put_line('+++++++++++++++++++++++++');
end;
Note: The newline character could be CHR(13) or CHR(10) or a combination of these two characters. The logic is the same.

Related

execute immediate ora-01704 string literal too long

I have the following code
BEGIN
EXECUTE IMMEDIATE 'CALL name_package.name_procedure('string literal too long...')';
END;
when I run it I get the following error:
ORA-01704: string literal too long
ORA-06512: line 2
01704. 00000 - "string literal too long"
*Cause: The string literal is longer than 4000 characters.
*Action: Use a string literal of at most 4000 characters.
Longer values may only be entered using bind variables.
I have tried with a variable clob but the error persists, some idea of how to solve this issue, i am using oracle 11g
Use a bind variable:
DECLARE
str CLOB := EMPTY_CLOB();
BEGIN
-- Make a long (random) string:
FOR i IN 1 .. 10 LOOP
str := str || DBMS_RANDOM.STRING( 'a', 4000 );
END;
-- Pass it into the dynamic SQL:
EXECUTE IMMEDIATE 'CALL name_package.name_procedure( :1 )' USING str;
-- Or just call the procedure without dynamic SQL:
name_package.name_procedure( str );
END;
Unclear what you are trying to accomplish. Within a PL/SQL block you would need only reference name_package.name_procedure('string'). Assuming name_procedure is defined in the specification of name_package.
BEGIN
name_package.name_procedure('string');
END;
CLOB variable would work in place of 'string' but only if that parameter is defined as CLOB and not as VARCHAR2.
EXECUTE IMMEDIATE requires a string. Quotes within a quoted string need to be presented twice.

ORA-06502: Numeric or Value Error on very basic string function, what gives?

Here's the code... this isn't the complete code. I trimmed it down to where the first error occurred:
FUNCTION get (
p_sql_o OUT VARCHAR2
) RETURN VARCHAR2 AS
str_sql VARCHAR2(4000);
BEGIN
str_sql := ' SELECT * FROM ( SELECT A.*, ROWNUM RNUM FROM ( ' ||
' SELECT item_code, ' ||
' item_desc, ' ||
' monitor, ' ||
' measured, ' ||
' inventory, ' ||
' (measured - inventory) adj_amount, ' ||
' (inventory_cost * measured) measured_cost, ' ||
'inventory';
RETURN str_sql;
EXCEPTION
WHEN OTHERS THEN
RETURN NULL;
END get;
Obviously, the SQL is incomplete, but I'm not running it. I'm simply returning the SQL string, yet I still get an error:
ORA-06502: PL/SQL: numeric or value error: character string buffer too small
ORA-06512: at line 6
This is baffling. Does anyone have any clue as to why this would be the case?
Since you've said you aren't attempting to dynamically execute the SQL you're creating, the syntax and correctness of what's in there, or the length of what it might return, is clearly irrelevant. You aren't doing anything with your p_sql_o OUT parameter, so that isn't causing this problem either. That only really leaves str_sql as the culprit, and as Justin implied yesterday, it's declared as large enough within the function and the function itself compiles OK - so it looks like it has to be how it's being called that's the problem.
You mentioned it works if you remove the 'inventory', which reduced the length of that string from 201 to 192 characters, so I'm guessing you've got this set to 200 chars in the caller, something like:
declare
str_sql varchar2(200);
p_sql_o varchar2(4000);
begin
str_sql := get(p_sql_o);
end;
/
declare
*
ERROR at line 1:
ORA-06502: PL/SQL: numeric or value error: character string buffer too small
ORA-06512: at line 5
Note that the line number this is reporting is 5, not 6 as you had; it's the line in the caller that has the error, not the line the assignment happens inside the function. If I make it str_sql varchar2(250); in the caller declaration then it works (but it might as well be 4000 to match the declaration in the function).
declare
str_sql varchar2(250);
p_sql_o varchar2(4000);
begin
str_sql := get(p_sql_o);
end;
/
PL/SQL procedure successfully completed.
But p_sql_o will still be empty because you never set it. It looks like the OUT parameter is redundant. Perhaps you meant to put the SQL string into that instead, and that is already declared as big enough in the caller; but then it isn't clear what the return value would be - you probably just want to remove the OUT parameter completely, and make sure the variable in the caller that you're putting the return value into is large enough.
Have you tried just running the SQL script against the DB outside of the SP? This will help to determine if the sql syntax is correct and that you are returning what is expected. It looks like you expect to get a response that is 4000 bytes or smaller. Are you sure that is what is being returned? I don't see Where clause. Maybe you are returning multiple rows that exceed your limit? Admittedly, I'm not as familiar with stored procedures, so I could be off.
Here you are using p_sql_o as out parameter and not assigning any value inside your function.
So p_sql_o will hold the value it had previously in the code follows after calling line of this function.
As you defined str_sql can hold only 4000 char, if your concatenated string is going beyond that limit it will give character string buffer too small ORA-06512 error.
When you are concatenating the string to create a select statement, check if you are using the single quotes properly or you are missing them at all. If this is happening then while executing the dynamic select statement you may get this error ORA-06502: PL/SQL: numeric or value error:

Error : ORA-01704: string literal too long

While I try to set the value of over 4000 characters on a field that has data type CLOB, it gives me this error :
ORA-01704: string literal too long.
Any suggestion, which data type would be applicable for me if I have to set value of unlimited characters although for my case, it happens to be of about 15000 chars.
Note : The long string that I am trying to store is encoded in ANSI.
What are you using when operate with CLOB?
In all events you can do it with PL/SQL
DECLARE
str varchar2(32767);
BEGIN
str := 'Very-very-...-very-very-very-very-very-very long string value';
update t1 set col1 = str;
END;
/
Proof link on SQLFiddle
Try to split the characters into multiple chunks like the query below and try:
Insert into table (clob_column) values ( to_clob( 'chunk 1' ) || to_clob( 'chunk 2' ) );
It worked for me.
To solve this issue on my side, I had to use a combo of what was already proposed there
DECLARE
chunk1 CLOB; chunk2 CLOB; chunk3 CLOB;
BEGIN
chunk1 := 'very long literal part 1';
chunk2 := 'very long literal part 2';
chunk3 := 'very long literal part 3';
INSERT INTO table (MY_CLOB)
SELECT ( chunk1 || chunk2 || chunk3 ) FROM dual;
END;
Hope this helps.
The split work until 4000 chars depending on the characters that you are inserting. If you are inserting special characters it can fail.
The only secure way is to declare a variable.
Though its a very old question but i think sharing experience still might help others:
Large text can be saved in a single query if we break-down it in chunks of 4000 bytes/characters by concatinating them using '||'
Running following query will tell you:
Required Number of chunks containing 4000 bytes
Remaining bytes
Since, in given example you are trying to save text contining 15000 bytes (characters), so,
select 15000/4000 chunk,mod(15000,4000) remaining_bytes from dual;
Result:
That means, you need to concatenate 3 chunks of 4000 bytes and one chunk of 3000 bytes, so it would be like:
INSERT INTO <YOUR_TABLE>
VALUES (TO_CLOB('<1st_4K_bytes>') ||
TO_CLOB('<2nd_4K_bytes>') ||
TO_CLOB('<3rd_4K_bytes>') ||
TO_CLOB('<last_3K_bytes>)');
create a function that return a clob
create function ret_long_chars return clob is
begin
return to_clob('put here long characters');
end;
update table set column = ret_long_chars;
INSERT INTO table(clob_column) SELECT TO_CLOB(q'[chunk1]') || TO_CLOB(q'[chunk2]') ||
TO_CLOB(q'[chunk3]') || TO_CLOB(q'[chunk4]') FROM DUAL;
Accepted answer did not work for me in sql developper but combination of this answer and another one did :
DECLARE
str varchar2(32767);
BEGIN
update table set column = to_clob('Very-very-...-very-very-very-very-very-very long string value');
END;
/

DBMS_LOB.SUBSTR() throwing "character string buffer too small" error

Does oracle have a method to get substring based on number of bytes from a CLOB field?
select DBMS_LOB.SUBSTR(a.COMMENTS, 3998, 1)
FROM FOO;
I am getting error:
"ORA-06502: PL/SQL: numeric or value error: character string buffer
too small"
.
The problem was in special characters. Each new special character takes 8 bytes so when I reduce the string limit to 3992 then it works.
DBMS_LOB.SUBSTR(a.COMMENTS, 3992, 1) works.
For testing purpose I put many special characters and again it throws same error.
Does oracle have any method which finds substring based on number of bytes than number of characters?
Actually, we are fetching data from a table and need to display on UI with a limitation of 4000 characters. So, we want to fetch first 4000 characters only. As, a character size is 1 byte, we can accomodate 4000 bytes. So, if we use DBMS_LOB.CONVERTTOBLOB, we may not be able to display properly the characters string fetched. Can we convert it back it charater string somehow?
I used the old SUBSTR function successfully, which works for the clob type as well. In this case, it's SUBSTR(a.COMMENTS, 1, 3992)
It's an old problem, but I did not find any solution to it, so I will post my approach to find solution for this problem, just in case someone needs to handle this...
My task was to retrieve "the most" characters from CLOB..
DBMS_LOB.SUBSTR nor SUBSTR will achieve the correct result...
In case of using DBMS_LOB.SUBSTR I keep getting ORA-12801 with ORA-06502
Using SUBSTR another ORA-64203..
Suggestions say to do SUBSTR for max 1000, because maximum number of bytes for character is 4, therefore You won't get more then 4000 bytes, unfortunately that's not good enough for me, because You might receive only 2000 bytes this way, in case that certain row does not contain multi-byte characters...
My solution, which shouldn't be used for repeated queries by the way (rather for extracting and loading/storing data into VARCHAR2 column), is:
create or replace FUNCTION SUBSTR_MULTIBYTE_CLOB
(
P_DATA IN CLOB
, P_START_INDEX IN NUMBER
) RETURN VARCHAR2 AS
P_OUT VARCHAR2(4000 BYTE);
P_LENGTH NUMBER := 4000;
BEGIN
FOR loop_counter IN 1..400 LOOP
BEGIN
P_OUT := DBMS_LOB.SUBSTR(P_DATA,P_LENGTH-((loop_counter-1)*10),P_START_INDEX);
RETURN P_OUT;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE = -12801 OR SQLCODE = -6502 OR SQLCODE = -1401 OR SQLCODE = -1489 THEN
NULL; -- suppresses ORA-12801 "error signal from parallel server" or ORA-06502 exception "character string buffer too small" and some others I've got...
ELSE
RAISE;
END IF;
END;
END LOOP;
END SUBSTR_MULTIBYTE_CLOB;
If needed, You can change loop to 4000 and decrease it by one byte, I've decided to go by 10, just to make it little bit faster...
try this method::
Use Oracle function LENGTHB() to get this result. there is a way around convert CLOB to BLOB by using DBMS_LOB.CONVERTTOBLOB and use DBMS_LOB.GET_LENGTH(). this is will return no of bytes.
You can use this thread for complete answer ::
https://forums.oracle.com/forums/thread.jspa?threadID=2133623
First, try to replace all special characters from the Character string and then try to substring it to convert it to Character.
Example:- DBMS_LOB.SUBSTR(REGEXP_REPLACE(your_column, '[^0-9A-Za-z]', ''),3999,1)

concatenating 2 strings issue in Oracle

I have another issue that I do not know what has caused it. I am new to Oracle and I am tumbling on concatenating 2 strings. I have a function that is going to take a DateStart, DateStop and other variables then turn them into a SQL stmt. The function was compiling fine but has the following error when executed:
ORA-06502: PL/SQL: numeric or value error: character string buffer too small ORA-06512 at line ...
At first I thought that one of the strings might be missing a quote, but both of the strings are fine as the function did not generate error when I printed the single one out. It had issue only when both of them are combined!
It may be something obvious that I have overlooked, I have even tried concat instead of the operator "||", but I was not able to pin point the cause of the issue. If someone has come across this issue before, I would appreciate it if you could give me a hint of what I was doing incorrectly.
This is the function that caused me issue, I have trimmed out all other irrelevant codes so that we could zero in the problem. The function compiled correctly but had issue when executed.
Thanks!
create or replace
FUNCTION ABC(
DateStart IN VARCHAR2 ,
DateStop IN VARCHAR2 ,
ZipCode IN VARCHAR2 ,
PracticeID IN VARCHAR2)
RETURN VARCHAR2
IS
v_code NUMBER;
v_errm VARCHAR2(64);
sqlstmt VARCHAR2(1000);
sqlstmt2 VARCHAR2(500);
sConditionClause VARCHAR2(500);
s_Quote VARCHAR(1) := chr(39);
BEGIN
sqlstmt2 :='SELECT TO_CHAR("Date", ''yyyy-mm-dd'') AS "Date" ,
substr(trim("Postal"),1,5) AS "ZipCode" ,
count ("Patient") AS "Total" ';
sConditionClause := ' FROM "ABC_TABLE" WHERE "Date">=To_Date('
||s_Quote || trim(DateStart) ||s_Quote
||','
||s_Quote||'mm/dd/yyyy'||s_Quote||')AND "Date"<=To_Date('
||s_Quote || trim(DateStop) ||s_Quote
||','||s_Quote||'mm/dd/yyyy'||s_Quote||') ';
sqlstmt := trim(sqlstmt2)||trim(sConditionClause);
RETURN sqlstmt;
END;
One of your variables (sqlstmt2, sConditionClause, or sqlstmt) is too small for the string you're trying to assign to it. If you had included the line number that the error is occurring on, we'd know which one.
Incidentally, you can use two single quotes together to add a single quite to a string, rather than having to use s_Quote as you are.
You could avoid this issue altogether by skipping the local variables:
create or replace
FUNCTION ABC(
DateStart IN VARCHAR2,
DateStop IN VARCHAR2)
RETURN VARCHAR2
IS
BEGIN
RETURN 'SELECT TO_CHAR("Date", ''yyyy-mm-dd'') AS "Date" ,
substr(trim("Postal"),1,5) AS "ZipCode" ,
count ("Patient") AS "Total"
FROM "ABC_TABLE" WHERE "Date">=To_Date('''
|| trim(DateStart)
||''',''mm/dd/yyyy'') AND "Date"<=To_Date('''
|| trim(DateStop)
||''',''mm/dd/yyyy'')';
END ABC;
This is what I found out: The function above may not have issue and the concatenation was fine. The issue was from the unit test Run PL/SQL provided by SQL Developer. It defaulted the return value string with a length of 200 char?!. I was not familiar enough with SQL Developer to discover it and blamed on my own function. As soon as I changed the length of the return string to varchar2(5000) everything run like a charm

Resources