0

I have following query, Which I am trying to split by "Name:". The output will be inserted into table as follows. But it doesn't work as expected.

jsab
sim
karksd,ad

create or replace procedure p_ins (par_string in varchar2) is
    begin
    insert into TBL_TEST (Name)
    select trim(regexp_substr(par_string, '[^Name:]+', 1, level))
       from dual
         connect by level <= regexp_count(par_string, 'Name:') + 1;
  end;
  
  exec p_ins('Name:jsab,Name:sim,Name:karksd,ad');
3
  • 1
    [^Name:] in your original regex means "All characters except 'N', 'a', 'm', 'e', and ':'". It does not apply any ordering, so "Name:" will be excluded, but so will "N", "me", "aN:em", and all other combinations of those five characters. I don't know of a way to say "don't match this string" in a regular expression - instead, what I've seen done is to use () to make a subexpression out of the string that must exist but which isn't wanted in the result, and then to ignore that subexpression. As you use regex's more you'll become accustomed to this kind of thinking. :-) Commented Jun 4, 2022 at 15:27
  • @BobJarvis-СлаваУкраїні - It is not necessary to make a subexpression from the fragment that is required but not wanted in the result. What is necessary is to make a subexpression from the part that is required in the output. When you see the "required, not needed" fragment in parentheses (thus becoming a subexpression, even if not needed) is for other reasons. In my solution, the first occurrence is optional - it has to be, since except at the start of the input string, the "Name:" tag is consumed by the previous match; to apply the ? operator to the tag, the tag must be in parentheses. Commented Jun 4, 2022 at 17:08
  • @BobJarvis-СлаваУкраїні - In my solution, the "Name:" marker at the end is in parentheses only because I need an alternation: a "token" ends either with the marker or with end-of-string. The alternation is in parentheses (it must be), not the delimiter alone. Commented Jun 4, 2022 at 17:09

1 Answer 1

1
create table tbl_test (name varchar2(40));

create or replace procedure p_ins (par_string in varchar2) is
    begin
    insert into TBL_TEST (Name)
      select  regexp_substr(par_string,
                  '(Name:)?(.*?)(,Name:|$)', 1, level, null, 2)
      from    dual
      connect by level <= regexp_count(par_string, 'Name:');
  end;
/ 

exec p_ins('Name:jsab,Name:sim,Name:karksd,ad')

select * from tbl_test;


NAME                                    
----------------------------------------
jsab
sim
karksd,ad

NOTES

There are several mistakes in your code, in addition to the regular expression itself (which is clearly incorrect).

The PL/SQL code - the procedure - must be ended with a forward slash; it's missing from what you posted.

The count of names: it should equal the number of occurrences of 'Name:', why are you adding 1? (Answer: because you copied the answer from somewhere and modified it without understanding it).

exec is a SQL*Plus command; as such, it does not require a semicolon at the end. Semicolon is needed only for SQL statements and in PL/SQL code. Some IDE's will ignore the semicolon, but others will throw an error on it.

There is no need to trim the tokens from your string - at least not in the example string you used. Do you expect optional spaces in your strings?

The solution you were trying to adapt to your case works only when the separator is a single character, like comma. It doesn't work in your case. Do you understand what [^Name:] means in a regular expression? I'll bet the answer is "no", otherwise you wouldn't have tried that in your solution.

Sign up to request clarification or add additional context in comments.

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.