How to insert 2 million characters? - oracle

I need to insert 2 million characters in an Oracle database, but when I try to insert with a CLOB I have an error because its very long.
How can I insert 2 million characters in a field?
CREATE TABLE TABLA_CLOB(id number, valor CLOb default EMPTY_CLOB());
insert into TABLA_CLOB(id, valor) values (1,'DOCUMENT: ');
DECLARE
v_clob CLOB;
BEGIN
SELECT valor into v_clob from TABLA_CLOB where id=1 for update;
dbms_lob.writeappend(v_clob,200,'text with 2 million characters');
DBMS_OUTPUT.PUT_LINE(v_clob);
COMMIT;
END;

In PL/SQL & SQL, 'a value' is a text literal and the SQL documentation states:
Text literals have properties of both the CHAR and VARCHAR2 datatypes:
Within expressions and conditions, Oracle treats text literals as though they have the datatype CHAR by comparing them using blank-padded comparison semantics.
A text literal can have a maximum length of 4000 bytes.
Or for PL/SQL:
A string literal can hold up to 32,767 characters.
Split your 'text with 2 million characters' into 4k or 32k chunks and append each of those.

Related

VarChar can be composed of?

Can a varchar datatype consist numeric values and special characters in it?
If yes, please elaborate.
There's nothing much I'd like to elaborate. Documentation (11g version; pick any other you might be using) explains mostly everything:
The VARCHAR2 datatype stores variable-length character strings.
Example:
SQL> create table test (col varchar2(20));
Table created.
SQL> -- string
SQL> insert into test values ('abc');
1 row created.
SQL> -- number - implicitly converted to varchar2 datatype
SQL> insert into test values (100);
1 row created.
SQL> -- special characters - not exactly "special", as they are enclosed into
SQL> -- single quotes so they are actually treated as "strings", but yes - you
SQL> -- can store them into a varchar2 column as well
SQL> insert into test values ('#$%');
1 row created.
SQL> select * from test;
COL
--------------------
abc
100
#$%
SQL>
It is an indeterminate length string data type. It can hold numbers, letters and special characters.For varchar you need to check ASCII and EXTENDED ASCII character as these are allowed in a char/varchar field.

ORA-01704: string literal too long error update clob field

Can you advice on a method of doing updates on clob fields in Oracle?
The query is a simple one and running it I get
ORA-01704: string literal too long:
Update table_name
Set clob_field=value2
Where column=condition1 and clob_field=value1
The scope is to update the value in a clob column with a new value.
Thanks
Is Your code part of some PLSql procedure or it is simple SQL statement? Do You pass variable "value2" as bind variable or it is quoted string inside the query? Are You on 12c or some earlier release of Oracle DB?
Generally, the most common "not obvious" issue is related to the fact that varchar2 type is limited to 4000 characters in SQL statements. If You are in PLSql procedure, the limit is 32K characters.
Can You provide code sample? The fact is that following two statements result in different behavior:
update table_name
set clob_field=value2
where column=condition1
and clob_field=value1
update table_name
set clob_field='Some very long string.....end of very long string'
where column=condition1
and clob_field='Some even longer string.....end of even longer string'
Take a look at post Error : ORA-01704: string literal too long - example how to put update in plsql block in order to achieve 32.767 character limit.
edit:
Take a look at post Working with very large text data and CLOB column, too
As you may know, it is not possible to insert more than 4k characters at one time in a clob field with Oracle Database.
A workaround to solve this issue is to split the whole string in 2 string < 4k
Example :
create table t_test (id number, texte clob);
insert into t_test (id, texte) values(1, to_clob ('value of 3999 characters') || to_clob ('value of remaining 1001 characters'));
You can use the "Lorem ipsum" to do the test :-)
Put your string value to a CLOB variable first:
declare
c clob;
s varchar2(4000);
begin
s:=rpad('x',4000,'x');
for i in 1..100 loop
c:=c||s;
end loop;
dbms_output.put_line( dbms_lob.getlength(c) );
-- length of "c" is 400000 now
update table_name set clob_field=c where id=12345;
end;
/

Identifier Too long Exception

I have a query of more than 4000 characters which is formed from different varaibles having varchar2 datatype of size 2000
example
query1 varcahr2(2000):='string 1';
query2 varchar2(2000):='string2';
query3 varcahr2 (2000):= string3';
I have declared a variable query varchar2(32000)
query := query1|| query2 || query3 ;
create table t (
id number,
querystring varchar2(4000));
I tried to get the first 4000 characters from the query variable it is not working. Can anyone please help?
declare
querystring1 varchar2(2000) := "string1";
querystring2 varchar2(2000) := "string2";
l_query varchar2(32000);
query varchar2(4000);
begin
l_query := querystring1 || querystring2 ;
select substr(l_query,1,4000) into query from dual;
insert into lib_query_table values('1',query);
end;
You are using double quotes around your query string literals, instead of single quotes. That makes Oracle interpret them as identifier names - so as soon as your literal is more than 30 characters long you'll get that exception. With shorter strings you'd still get an error, but something like 'unknown identifier'.
Replace your double quotes with single ones:
declare
querystring1 varchar2(2000) := 'string1';
querystring2 varchar2(2000) := 'string2';
l_query varchar2(32000);
query varchar2(4000);
begin
l_query := querystring1 || querystring2 ;
select substr(l_query,1,4000) into query from dual;
insert into lib_query_table values (1, query);
end;
You don't need the query from dual, you can do:
query := substr(l_query, 1, 4000);
You could skip that variable and do:
insert into lib_query_table (id, querystring)
values (1, substr(l_query, 1, 4000);
or even:
insert into lib_query_table (id, querystring)
values (1, substr(querystring1 || querystring2, 1, 4000));
As your ID column is a number you should not insert the value for that as a string '1' - just use a number. You probably want a sequence to set that value, eventually.
Also not directly related, but when you're concatenating parts of a query together, say where one string is the select list and the second is the from clause etc., make sure you have whitespace at the end of each part (or the start of the next part), or the combined string might end up invalid.
Variable-length character string having maximum length size bytes or characters. You must specify size for VARCHAR2. Minimum size is 1 byte or 1 character. Maximum size is: 32767 bytes or characters if MAX_STRING_SIZE = EXTENDED 4000 bytes or characters .
You can look CLOB data type

Not able to insert 240 characters to Oracle DB using stored procedure

I am new to Oracle and is facing an issue while inserting 240 characters using Stored procedure. Below is the stored procedure:
procedure add_user_note(p_user_seq in varchar2,
p_author in varchar2,
p_note_text in varchar2,
o_return_code out integer) IS
BEGIN
o_return_code := RC_SUCCESS;
INSERT INTO user_notes
(sss_user_object_id, note_date, note_text, note_author)
VALUES
(p_user_seq, SysDate, p_note_text, p_author);
commit;
exception
when others then
o_return_code := SQLCODE;
END;
Using this procedure i can insert 238 characters, but my requirement is to insert 240 characters to parameter p_note_text. Any help is appreciated.
Your code does not restrict the number of characters in p_note_text. Your code can handle up to 32767 bytes, which is PLSQL max varchar2 length.
The number of characters you can insert is probably restricted by the column definition of user_notes.note_text.
See here a discussion about the difference about BYTE and CHAR in column definitions.
Difference between BYTE and CHAR in column datatypes
you should play with length() and lengthB() functions
Length - for char count
LengthB - for size in terms of byte

How to get around 4000 characters limitation of text_query in Oracle's CONTAINS operator?

In Oracle, the full text search syntax of Contains operator is:
CONTAINS(
[schema.]column,
text_query VARCHAR2
[,label NUMBER]) RETURN NUMBER;
which means the text_query can not be more than 4000 characters long or an error will occur. I repeatedly have text_query longer than 4000 characters long in many cases. How would you, as an Oracle expert, suggest to get around such limitation if possible?
To further clarify the situation in which 4000 is easily reached is that if you combine many Contains Query Operators to construct your text_query, it is quite possible to exceed such 4000 characters limitation.
The 4000 character limit is not some arbitrary boundary: it is the maximum amount of VARCHAR2 characters that Oracle SQL can handle.
4000 characters is a lot of text. In English it's around 600 words, or an A4 page and a bit in a reasonable point font. There are not many applications I can think of which require searching for such large chunks of verbiage. Even colleges checking students' essays for plagiarism would operate at no more than the paragraph level.
However, if you really have a situation in which matching on a scant 4000 characters generates false positives all you can do is split the query string into chunks and search on them. This means you have to use PL/SQL:
create or replace function big_search (p_search_text in varchar2)
return sys_refcursor
is
return_value sys_refcursor;
p_srch1 varchar2(4000);
p_srch2 varchar2(4000);
begin
dbms_output.put_line('search_length='||to_char(length(p_search_text)));
p_srch1 := substr(p_search_text, 1, 4000);
p_srch2 := substr(p_search_text, 4001, 4000);
open return_value for
select docname
, (score(1) + score(2))/2 as score
from t23
where contains ( text_column, p_srch1 , 1) != 0
and contains ( text_column, p_srch2 , 2) != 0;
return return_value;
end;
/
If you don't know the size of the search text beforehand, then you'll need to use dynamic SQL to assemble this. Note that passing null search terms to CONTAINS() will hurl DRG-50901: text query parser syntax error.
The current version supports now a CLOB parameter
CONTAINS(
[schema.]column,
text_query [VARCHAR2|CLOB]
[,label NUMBER])
RETURN NUMBER;
http://docs.oracle.com/cd/B28359_01/text.111/b28304/csql.htm#i997503

Resources