Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

Oracle string concatenation

Posted on 2009-07-15
12
Medium Priority
?
2,755 Views
Last Modified: 2013-12-19
I have 3 strings I want to concatenate, they exceed 4000 together:

decode(trim(C.TEST_DESC) || trim(C.KEY_ITMS) || trim(C.TEST_EXCPTN), null, 'No',

the first is 1951, second is 586, third is 2017 for a total of 4554

this of course works, which seriously, is all I need:
decode(substr(substr(C.TEST_DESC,1,5) || substr(C.KEY_ITMS,1,5) || substr(C.TEST_EXCPTN,1,5),1,5), null, 'No',

Because all I'm checking is if the first sets are all null or not...

But I want to understand this... So please help me...

This breaks:
decode(substr(substr(C.TEST_DESC,1,4000) || substr(C.KEY_ITMS,1,4000) || substr(C.TEST_EXCPTN,1,4000),1,4000)
So does this:
    decode(substr(trim(C.TEST_DESC) || trim(C.KEY_ITMS) || trim(C.TEST_EXCPTN),1,5), null, 'No',

Shouldn't the outside substr be enough? Taking the final string and making sure it is 4000? But it doesn't. Even with an addtional subtr wrap on all the columns, it still breaks.

What would one do with this if one reallly wanted to return 4000 characters of all of them concatenated?

Because I do have existing SP's that use this type of concatenation everywhere so I want to make certain I can fix any further issues.

Thanks!
0
Comment
Question by:Starr Duskk
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 6
  • 3
  • 2
  • +1
12 Comments
 
LVL 40

Expert Comment

by:mrjoltcola
ID: 24861044
>>Shouldn't the outside substr be enough? Taking the final string and making sure it is 4000?

I fear not. Not in SQLPLUS.

You may need to either write a stored procedure in PL/SQL (which can go to 32k for varchar) or change to use a CLOB
0
 
LVL 40

Expert Comment

by:mrjoltcola
ID: 24861058
>>Because I do have existing SP's that use this type of concatenation

Yes, PL/SQL can do a 32k varchar. That is why.
0
 
LVL 2

Author Comment

by:Starr Duskk
ID: 24861060
this *is* in a stored procedure.
It's part of a select query in a stored procedure.
How would I "fix" this using 4000?
 
0
Prepare for your VMware VCP6-DCV exam.

Josh Coen and Jason Langer have prepared the latest edition of VCP study guide. Both authors have been working in the IT field for more than a decade, and both hold VMware certifications. This 163-page guide covers all 10 of the exam blueprint sections.

 
LVL 2

Author Comment

by:Starr Duskk
ID: 24861069
Your response doesn't add up to me. You say it will work in a stored procedure. yet this is a stored procedure and it doesn't work.
Does it have to do with it being inside the Decode?
 
0
 
LVL 20

Expert Comment

by:flow01
ID: 24861117
Move the concatenation from the select.
(= select the different columns in the select and do the concation of the columns in de pl/sql-code of the procedure)
Within the select you use the sql-engine and not the pl/sql so you can't fixed the 4000 limit.
0
 
LVL 40

Expert Comment

by:mrjoltcola
ID: 24861153
>>Does it have to do with it being inside the Decode?

No. It has to do with being SQL. You cannot select more than a 4k in any one varchar in a SQL statement, even inside PL/SQL. You can select 4k each into s1, s2 and s3 and then concat inside the procedure, but you would not be able to return more than 4k to a caller. I will provide a working sample, give me a minute.


0
 
LVL 2

Author Comment

by:Starr Duskk
ID: 24861169
the select is building a result_cursor, so I have to concatenate within the select...
OPEN rslt_cursor FOR
 
0
 
LVL 40

Accepted Solution

by:
mrjoltcola earned 1200 total points
ID: 24861230
You are going to have to decide on another option. You cannot return more than 4k in a VARCHAR2 in Oracle in a SQL statement or cursor, period. The only deviation from this is inside PL/SQL in host language, not SQL language.

See below for what I am saying, then we can discuss alternatives. Until you believe me we really cannot discuss alternatives.

create table a(s1 varchar2(4000), s2 varchar2(4000), s3 varchar2(4000));


-- Populate 1 row with 3 varchars of 4000 len
declare
   s varchar2(4000);
begin
   for i in 1..4000 loop
     s := s||'X';
   end loop;
   insert into a values(s, s, s);
end;
/



create or replace function bigstr return varchar2
as
  s varchar2(32000);
  s1 varchar2(4000);
  s2 varchar2(4000);
begin
  select s1, s2 into s1, s2 from a;
  s := s1||s2;  -- statement works, inside PL/SQL
 
  return s;  -- will cause error to caller, returning back to SQL
end;
/


Function created.

SQL> select bigstr from dual;
select bigstr from dual
       *
ERROR at line 1:
ORA-06502: PL/SQL: numeric or value error: character string buffer too small
ORA-06512: at "MSMITH.BIGSTR", line 10

0
 
LVL 20

Assisted Solution

by:flow01
flow01 earned 800 total points
ID: 24861239
you could create a function xx

decode(substr(substr(C.TEST_DESC,1,4000) || substr(C.KEY_ITMS,1,4000) || substr(C.TEST_EXCPTN,1,400

function xx (p_desc varchar2, p_itms varchar2, etct.. )return varchar2
is
  v_concat varchar2(30000);
  v_result varchar2(4000);
begin
     v_concat := p_desc || p_ttms ||  ...ect);
     -- do more
     if  ..   then
        v_result :=
     else
       v_result :=
    end if;
     return v_result;
end;
/

select  xx(C.TEST_DESC,C.KEY_ITMS,,,, ) from ..

!!! using pl/sql functions within sql has great possibilities but the switch between pl/sql engine and sql-engine is bad for performance
0
 
LVL 40

Assisted Solution

by:mrjoltcola
mrjoltcola earned 1200 total points
ID: 24861246
I propose you do the substr inside the function, then return 4k legal varchar2.

create or replace function bigstr return varchar2
as
  s varchar2(32000);
  s1 varchar2(4000);
  s2 varchar2(4000);
  s3 varchar2(4000);
begin
  select s1, s2, s3 into s1, s2, s3 from a;
  s := s1||s2||s3;
  s := substr(s, 1, 4000);
  return s;
end;
/

Open in new window

0
 
LVL 40

Expert Comment

by:mrjoltcola
ID: 24861257
flow01 and I are heading in the same direction. :)
0
 
LVL 48

Expert Comment

by:schwertner
ID: 24861484
You can use many parameters in the PROCEDURE

CREATE PROCEDURE (l OUT integer, p1 OUT varchar2, p2 OUT varchar2,
p3 OUT varchar2, p4 OUT varchar2) IS
.......


In the procedure use a variable that puts the whole string.
Make a block that using SUBSTR divides it in chunks and stores the chunks (4000 bytes) in p1,p2,p3,p4  Put the total length in l.

This is one possible solution.
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Working with Network Access Control Lists in Oracle 11g (part 2) Part 1: http://www.e-e.com/A_8429.html Previously, I introduced the basics of network ACL's including how to create, delete and modify entries to allow and deny access.  For many…
Configuring and using Oracle Database Gateway for ODBC Introduction First, a brief summary of what a Database Gateway is.  A Gateway is a set of driver agents and configurations that allow an Oracle database to communicate with other platforms…
This video shows how to Export data from an Oracle database using the Datapump Export Utility.  The corresponding Datapump Import utility is also discussed and demonstrated.
This video shows how to configure and send email from and Oracle database using both UTL_SMTP and UTL_MAIL, as well as comparing UTL_SMTP to a manual SMTP conversation with a mail server.

721 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question