19

I have a clob variable, need to assign it to varchar2 variable. The data inside clob var is less than 4000 (i..e varchar2's maxsize) oracle10+

I tried

  report_len  := length(report_clob);
  report      := TO_CHAR(dbms_lob.substr(report_clob, report_len, 1 ));
  report_clob := null;

but it turns report into long value which I see while debugging. Also when I call this sql (proc) from my C# code. It complains saying buffer too small, because I send parameter as per varchar, but the above conversion might be turning it into long value.

I even tried direct assignment

   report_clob := report 

getting the same result.

EDIT

Ok, to answer the questions below please see: I debug using test script in PL/SQL developer. report variable is varchar2(4000). When I step after 2nd line. report shows to be a long value and it just says (Long Value) . cant even see the contents.

report and report_clob are out variable from the procedure. This procedure is called from C# code.

There is an exception string buffer too small in C# when I call this procedure. I have given 5000 as size of report variable in C# sufficient to receive 4000 max characters value from the procedure. So I guess problem doesn't lie there.

And when I assign report:= 'some string....' then C# call works fine.

So my investigation says that report := transform (report_clob) is making report become long value or some such thing (weird) which makes C# code problematic to handle larger value in 5000 varchar out parameter.

Any more detail I will be happy to provide.

TravisO
  • 9,406
  • 4
  • 36
  • 44
Munish Goyal
  • 1,379
  • 4
  • 27
  • 49
  • How is `report` declared? `LONG` or `VARCHAR2`? How are you debugging, and how are you returning the value to `c#` - function return or output parameter, and what type is that? – Alex Poole Oct 12 '12 at 14:09
  • 2
    `report := CAST(report_clob AS VARCHAR2(3999));` – Anjan Biswas Oct 12 '12 at 14:14
  • 1
    `DBMS_LOB.substr` returns a VARCHAR2, you don't need the `TO_CHAR` function. Also what do you call a long value? How do you debug? What message error exactly are you getting (ie Oracle or C#)? How is the report variable declared? – Vincent Malgrat Oct 12 '12 at 14:16
  • pls see update in my question EDIT area – Munish Goyal Oct 15 '12 at 07:48
  • possible duplicate of [Why is my VARCHAR2 being converted to a LONG in my PL/SQL?](http://stackoverflow.com/questions/14838274/why-is-my-varchar2-being-converted-to-a-long-in-my-pl-sql) – Jon Heller May 10 '13 at 05:58
  • @jonearles How does that corroborate to the fact that the C# code is/was throwing "String buffer" error? – Anjan Biswas Apr 07 '14 at 19:29

4 Answers4

23

Quote (read here)-

When you use CAST to convert a CLOB value into a character datatype or a BLOB value into the RAW datatype, the database implicitly converts the LOB value to character or raw data and then explicitly casts the resulting value into the target datatype.

So, something like this should work-

report := CAST(report_clob AS VARCHAR2(100));

Or better yet use it as CAST(report_clob AS VARCHAR2(100)) where ever you are trying to use the BLOB as VARCHAR.

Anjan Biswas
  • 7,746
  • 5
  • 47
  • 77
  • 1
    When using `CAST(...)` in a select, you need to specify size e.g. `VARCHAR2(20)` – Wassadamo Jul 08 '20 at 21:04
  • Exactly, @Wassadamo. I struggled with it for quite a while before realizing. – Ganesh Jadhav Sep 11 '20 at 15:08
  • 1
    Unfortunately, this doesn't work for cases when CLOB data is large - I got the exception ORA-22835: Buffer too small for CLOB to CHAR... I ended up truncating the CLOB to 4000 characters or less, and then converting the truncated result to varchar - by using the function from this answer: https://stackoverflow.com/a/12778244/19032206 – qaziqarta Jun 15 '23 at 10:31
4

Converting VARCHAR2 to CLOB

In PL/SQL a CLOB can be converted to a VARCHAR2 with a simple assignment, SUBSTR, and other methods. A simple assignment will only work if the CLOB is less then or equal to the size of the VARCHAR2. The limit is 32767 in PL/SQL and 4000 in SQL (although 12c allows 32767 in SQL).

For example, this code converts a small CLOB through a simple assignment and then coverts the beginning of a larger CLOB.

declare
    v_small_clob clob := lpad('0', 1000, '0');
    v_large_clob clob := lpad('0', 32767, '0') || lpad('0', 32767, '0');
    v_varchar2   varchar2(32767);
begin
    v_varchar2 := v_small_clob;
    v_varchar2 := substr(v_large_clob, 1, 32767);
end;

LONG?

The above code does not convert the value to a LONG. It merely looks that way because of limitations with PL/SQL debuggers and strings over 999 characters long.

For example, in PL/SQL Developer, open a Test window and add and debug the above code. Right-click on v_varchar2 and select "Add variable to Watches". Step through the code and the value will be set to "(Long Value)". There is a ... next to the text but it does not display the contents. PLSQL Developer Long Value

C#?

I suspect the real problem here is with C# but I don't know how enough about C# to debug the problem.

Jon Heller
  • 34,999
  • 6
  • 74
  • 132
3
ALTER TABLE TABLE_NAME ADD (COLUMN_NAME_NEW varchar2(4000 char));
update TABLE_NAME set COLUMN_NAME_NEW = COLUMN_NAME;

ALTER TABLE TABLE_NAME DROP COLUMN COLUMN_NAME;
ALTER TABLE TABLE_NAME rename column COLUMN_NAME_NEW to COLUMN_NAME;
panser
  • 1,949
  • 22
  • 16
0

This is my aproximation:

  Declare 
  Variableclob Clob;
  Temp_Save Varchar2(32767); //whether it is greater than 4000

  Begin
  Select reportClob Into Temp_Save From Reporte Where Id=...;
  Variableclob:=To_Clob(Temp_Save);
  Dbms_Output.Put_Line(Variableclob);


  End;
Esneyder
  • 471
  • 1
  • 5
  • 19