2

I'm using Oracle 11g and I'm having trouble replacing multiple characters based on positions mentioned in a different table. For example:

Table 1

PRSKEY POSITION CHARACTER
  123     3         ć
  123     9         ć

Table 2

PRSKEY   NAME 
  123   Becirovic

I have to replace the NAME in Table 2 to Bećirović. I've tried regexp_replace but this function doesn't provide replacing more then 1 position, is there an easy way to fix this?

4
  • I think to have any chance of doing this you'd need to get your string into a single record with all the applicable replacement rules (2 in your example above). I don't see a way to do this. May we ask how you ended up with this problem? Commented Aug 24, 2017 at 13:10
  • I think the best way would be a function. Can you create functions in the environment? Commented Aug 24, 2017 at 13:23
  • @TimBiegeleisen I would join the tables, add group by and add LISTAGG() function (for MySQL the same is GROUP_CONCAT). Need to order group members and cut strings to have multiple pieces. Should work but the query would be tricky. Easier to introduce a function. Commented Aug 24, 2017 at 13:42
  • @StanislavL Yeah, I imagined something like this, and then got discouraged. My feeling was that the data model should change rather than performing such SQL olympics. Commented Aug 24, 2017 at 13:45

3 Answers 3

1

Here's another way to do it.

with tab1 as (select 123 as prskey, 3 as position, 'ć' as character from dual
            union select 123, 9, 'ć' from dual),
     tab2 as (select 123 as prskey, 'Becirovic' as name from dual)
select listagg(nvl(tab1.character, namechar)) within group(order by lvl) 
from
  (select prskey, substr(name, level, 1) as namechar, level as lvl
    from tab2
    connect by level <= length(name)
  ) splitname
left join tab1 on position = lvl and tab1.prskey = splitname.prskey
;
Sign up to request clarification or add additional context in comments.

1 Comment

really nice sollution
0

Simple solution using cursor ...

create table t1 (
  prskey int,
  pos int,
  character char(1)
);

create table t2
(
  prskey int,
  name varchar2(100)
);

insert into t1 values (1, 1, 'b');
insert into t1 values (1, 3, 'e');

insert into t2 values (1, 'dear');


begin
  for t1rec in (select * from t1) loop    
    update t2
    set name = substr(name, 1, t1rec.pos - 1) || t1rec.character || substr(name, t1rec.pos + 1, length(name) - t1rec.pos)
    where t2.prskey = t1rec.prskey;
  end loop;
end;
/

3 Comments

I did @Radim Baca ;-). Quick question: Is there a way to wrap this cursor into a stored procedure?
@Erwin sure, do you have any specific parameters in mind for that procedure?
To be honest I don't know wether I need a procedure or a function. The example I gave has a name without special characters that must be transformed into a name with special characters.So I would like to have a procedure or function (probably better) that automaticly returns the value with special characters based on the "PRSKEY"-value.
0

I would prefer approach via PL/SQL, but in your tag only 'sql', so I made this monster:

with t as (
  select 123 as id, 3 as pos, 'q' as new_char from dual
  union all
  select 123 as id, 6 as pos, 'z' as new_char from dual
  union all
  select 123 as id, 9 as pos, '1' as new_char from dual
  union all
  select 456 as id, 1 as pos, 'A' as new_char from dual
  union all
  select 456 as id, 4 as pos, 'Z' as new_char from dual
),
t1 as (
  select 123 as id, 'Becirovic' as str from dual
  union all
  select 456 as id, 'Test' as str from dual
)                    
select listagg(out_text) within group (order by pos) 
from( 
  select id, pos, new_char, str, prev, substr(str,prev,pos-prev)||new_char as out_text
  from(
    select id, pos, new_char, str, nvl(lag(pos) over (partition by id order by pos)+1,1)  as prev
    from (
      select t.id, pos, new_char, str
      from t, t1
      where t.id = t1.id
    ) q
  ) a
) w
group by id

Result:

Beqirzvi1
AesZ

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.