REGEXP_LIKE help

Hello,
Been scouring the web looking for some help using the REGEXP_LIKE syntax. Haven't found a precise answer, but I think I wrote my own correctly and just wanted to get some validation from other users.
Running Oracle 10.2
Sample Data:
create table test(data varchar2(10));
    insert into test values('01W00012');
    insert into test values('50321070');
    insert into test values('A1391010');
    insert into test values('ZZ260010');
    insert into test values('29374C01');
    insert into test values('A938523A');
    insert into test values('23W48AC3');
    insert into test values('DKFUGHCK');
    insert into test values('09W00032');
    insert into test values('94857283');
    insert into test values('AB-29348');
    insert into test values('98W-8923');
    insert into test values('0AW00005');
    insert into test values('04300W05');
    commit;What I'm trying to do:
I have a table containing millions of work orders. They are all of length 8. I want to find all work orders where the first 2 characters are a digit only, the third character is a 'W', and the last 5 characters are digits only. Anything else I want to throw away. I think I came up with a working expression... but I'm always hesitant when running it against millions of rows. Here was what I did:
select * from test
    where regexp_like(data, '(^[0-9]{2}W{1}[[:digit:]]{5})');There are exactly 2 occurrences from up above that match the criteria I'm trying to meet.
Is this expression properly written?
Any help would be greatly appreciated.... reg expressions always make my head spin :(

Hi,
dvsoukup wrote:
Running Oracle 10.2
Sample Data: ...Thanks for posting that; it's really helpful!
What I'm trying to do:
I have a table containing millions of work orders. They are all of length 8. I want to find all work orders where the first 2 characters are a digit only, the third character is a 'W', and the last 5 characters are digits only. Anything else I want to throw away. I think I came up with a working expression... but I'm always hesitant when running it against millions of rows. Here was what I did:
select * from test
where regexp_like(data, '(^[0-9]{2}W{1}[[:digit:]]{5})');There are exactly 2 occurrences from up above that match the criteria I'm trying to meet.
Is this expression properly written?Yes, that's a good regular expression. However, a very important thing about regular expressions is that you should only use them when you really need to. In this case, you can get the results you want more efficiently, and at least as easily, without regular expressions. Here's one way:
SELECT  *
FROM     test
WHERE   TRANSLATE ( data
            , '012345678'
            , '999999999'
            )          = '99W99999'
;This will be more efficient than using REGEXP_LIKE, and it sounds like efficiency is important in this case.
If you really want to use a regular expression, there are a couple of small things you can do to make it clearer. (With regular expressions, every little bit helps.)
(a) If you're certain that data is always exactly 8 characters, then you don't need the ^ anchor at the beginning. If you want the regular expression to check that the length is 8 characters, then keep the ^ anchor at the beginning, but use a $ anchor at the end, too, as in the example below. As you posted it, the expression will be TRUE when data is longer than 8 characters, as long as the first 8 characters fit the pattern.
(b) [0-9] is equivalent to [[:digit:]]. Either one is fine, but I find it confusing to use both in the same expression. Use one or the other in both places.
(c) {1} is the default. I would just say 'W' instead of 'W{1}'
(d) You don't need the parentheses in this expression. If parentheses are not needed, but they improve clarity, then it's okay to include them. In this case, I don't think they add anything.
There are exactly 2 occurrences from up above that match the criteria I'm trying to meet.It helps if you post exactly what results you want. For example:
DATA
01W00012
09W00032In this case, I found your description very clear, but it doesn't hurt to post the actual results anyway.
Is this expression properly written?You might consider writing it this way, particularly if you think you'll need to debug it:
SELECT  *
FROM      test
WHERE      REGEXP_LIKE ( data
              , '^'          || -- beginning of string
                '[0-9]{2}'     || -- 2 digits
                'W'          || -- a capital W
                '[0-9]{5}'     || -- 5 more digits
                '$'             -- end of string
;As mentioned before, you only need the ^ and $ if you're not sure all the strings are exactly 8 characters.
... reg expressions always make my head spin All the more reason to use TRANSLATE.
Edited by: Frank Kulash on Jul 26, 2012 2:42 PM

Similar Messages

  • REGEXP_LIKE help with literal single-quote

    I'm trying to write a check constraint to validate email addresses that may include an apostrophe in the email address. Such as joe.o'[email protected] Here is my sample setup:
    create table emails
    ( email_address varchar2(150)
    insert into emails values('[email protected]') ;
    insert into emails values('[email protected]') ;
    insert into emails values('joey.o''[email protected]') ;
    commit;
    sql> select * from emails;
    EMAIL_ADDRESS
    [email protected]
    [email protected]
    joey.o'[email protected]
    alter table emails add constraint email_address_format_ck
        CHECK ( REGEXP_LIKE ( email_address, '^[a-z0-9._%-]\'?+@[a-z0-9._%-]+\.mil$','c'));
    ERROR at line 2:
    ORA-00911: invalid characterIt doesn't like *\'?*
    My understanding is this means one or more single-quotes. Anyone know the correct syntax to accept apostrophes?

    Hi,
    jimmyb wrote:
    ... insert into emails values('joey.o''[email protected]') ;
    That's the correct way (actually, that's one correct way) to include a single-quote in a string literal: use 2 single-quotes in a row.
    ... alter table emails add constraint email_address_format_ck
    CHECK ( REGEXP_LIKE ( email_address, '^[a-z0-9._%-]\'?+@[a-z0-9._%-]+\.mil$','c'));Here, the 2nd argument to REGEXP_LIKE is a string literal, just like 'joey.o''[email protected]' was a string literal.
    To include a single-quote in the middle of this string literal, do the same thing you did before: use 2 of them in a row:
    CHECK ( REGEXP_LIKE ( email_address, '^[a-z0-9._%''-]+@[a-z0-9._%-]+\.mil$','c'));There were a couple of other problems, too.
    I'm sure you meant for the apostrophe to be inside the square brackets. Inside square brackets, \ does not function as an escape character. (Actually, single-quote has no special meaning in regular expressions, so there's no need to escape it anyway.)
    I'm not sure what the '?' mark was doing; I left it out.
    Of course, you'll have trouble adding the CHECK constraint if any existing rows violate it.
    Edited by: Frank Kulash on Feb 10, 2012 6:52 PM

  • REGEXP_LIKE help - escaping the hyphen

    I need to match string that does not contain "dc-ba" - all are literal. It has to return true for all strings that is not "ab-cd".
    The hypen is creating the problem. If hypen were not there:
    select ('Matched') "Status" from dual where REGEXP_LIKE('def', '[^(^dcba$)]');
    Matchedselect ('Matched') "Status" from dual where REGEXP_LIKE('dcba', '[^(^dcba$)]');
    no rows returnedEverything is as required to this point, but when I try to apply the same with hypen:
    select ('Matched') "Status" from dual where REGEXP_LIKE('dc-ba', '[^(^dc-ba$)]');
    Error: ORA-12728: Invalid range in regular expression
    If I try to escape the hyphen:
    select ('Matched') "Status" from dual where REGEXP_LIKE('dc-ba', '[^(^dc\-ba$)]');
    MatchedWhich sould not be the case. It shoudl match all string other than "dc-ba".
    Am I doing something wrong?

    Tubby,
    it is not just a question of replacing all the hyphens with something that's "special" that won't mess with the regular expression. First of all, that "special" can never occur in source data. For example, replacing hyphens with tilda could result in rejecting dc~ba:
    SQL> select ('Matched') "Status" from dual where REGEXP_LIKE(REPLACE('dc~ba', '-','~'), REPLACE('[^(
    ^dc-ba$)]', '-','~'));
    no rows selected
    SQL> Secondly, there is over a dozen special meaning characters in regular expressions, so each of them must be replaced with a chatacter that can not appear in source data.
    SY.

  • About RegExp

    Hi All,
    I need to find out wheather given string is alphanumeric or perfect string.
    can REGEXP_LIKE help in this?
    IF REGEXP_LIKE(string,'[a-z]') THEN
    IF REGEXP_LIKE(string,'[0-9]') THEN
    string is alphanumeric
    END IF;
    END IF;
    Can we merge the both conditions in single REGEXP_LIKE call?
    We need exact match if both conditions means if strings contains alphbets as well as number then only returns true.
    Same if string contains only alphabets then return true.
    REGEXP_LIKE(string,'[a-z]')
    With above command if string contains string as well as number it returns TRUE, but we need exact match if string contains only alphabets then return TRUE.
    Thanks for your help.

    sandeep1983 wrote:
    Hi All,
    I need to find out wheather given string is alphanumeric or perfect string.
    can REGEXP_LIKE help in this?
    IF REGEXP_LIKE(string,'[a-z]') THEN
    IF REGEXP_LIKE(string,'[0-9]') THEN
    string is alphanumeric
    END IF;
    END IF;
    Can we merge the both conditions in single REGEXP_LIKE call?
    We need exact match if both conditions means if strings contains alphbets as well as number then only returns true.
    Same if string contains only alphabets then return true.
    REGEXP_LIKE(string,'[a-z]')
    With above command if string contains string as well as number it returns TRUE, but we need exact match if string contains only alphabets then return TRUE.
    Thanks for your help.you can use character sets:
    regexp_like(string,'[[:alnum:]]')or
    regexp_like(string,'[a-zA-Z0-9]')

  • Need help on regexp_like

    Hi Folks,
    Please help me out on my requirement which is based on regexp_like
    Example:
    prod_id and prod_desc are having values like
    1,'SAMUSUNG,NOKIA'
    2,'NOKIA,SAMUSUNG,APPLE'
    3,'NOKIA,APPLE,SAMUSUNG,HTC'
    4,'SAMUSUNG,NOKIA,APPLE,HTC,CELLKON'
    I want to fetch the values of prod_id and prod_desc as
    prod_desc should have SAMSUNG AND NOKIA BUT NOT HTC
    answer is :
    1,'SAMUSUNG,NOKIA'
    2,'NOKIA,SAMUSUNG,APPLE'

    Greg.Spall wrote:
    Easy enough using the documentation as reference:
    http://docs.oracle.com/cd/B12037_01/server.101/b10759/conditions018.htm
    WITH D AS(SELECT 1 prod_id, 'SAMUSUNG,NOKIA'  prod_desc FROM DUAL UNION ALL   
        SELECT 2,'NOKIA,SAMUSUNG,APPLE' FROM DUAL UNION ALL   
        SELECT 3,'NOKIA,APPLE,SAMUSUNG,HTC' FROM DUAL UNION ALL   
        SELECT 4,'SAMUSUNG,NOKIA,APPLE,HTC,CELLKON' FROM DUAL )   
    SELECT PROD_ID,PROD_DESC FROM D   
    WHERE NOT REGEXP_LIKE ( prod_desc, '*HTC*', 'i') 
      PROD_ID PROD_DESC                     
            1 SAMUSUNG,NOKIA                 
            2 NOKIA,SAMUSUNG,APPLE           
    2 rows selected.
    What if the string contains 'AHTCK'? Would that still be excluded? or only where 'HTC' exists between the commas?
    SQL> WITH D AS(SELECT 1 prod_id, 'SAMUSUNG,NOKIA'  prod_desc FROM DUAL UNION ALL 
    2  SELECT 2,'NOKIA,SAMUSUNG,APPLE' FROM DUAL UNION ALL 
    3  SELECT 3,'NOKIA,APPLE,SAMUSUNG,HTC' FROM DUAL UNION ALL 
    4  SELECT 4,'NOKIA,SAMUSUNG,AHTCK,APPLE' FROM DUAL UNION ALL 
    5  SELECT 5,'HTC,NOKIA,SAMUSUNG,APPLE' FROM DUAL UNION ALL 
    6  SELECT 6,'NOKIA,SAMUSUNG,APPLE,HTC' FROM DUAL UNION ALL 
    7  SELECT 7,'SAMUSUNG,NOKIA,APPLE,HTC,CELLKON' FROM DUAL UNION ALL 
    8  SELECT 8,'HTC' FROM DUAL ) 
    9  SELECT PROD_ID,PROD_DESC FROM D
    10  WHERE NOT regexp_like(PROD_DESC,',HTC,')
    11    AND NOT regexp_like(PROD_DESC,'^HTC,')
    12    AND NOT regexp_like(PROD_DESC,',HTC$')
    13    AND NOT regexp_like(PROD_DESC,'^HTC$')
    14  ; 
    PROD_ID PROD_DESC
    1 SAMUSUNG,NOKIA       
    2 NOKIA,SAMUSUNG,APPLE       
    4 NOKIA,SAMUSUNG,AHTCK,APPLE

  • Need help in REGEXP_LIKE

    Hi All,
    i need a help in REGEXP_LIKE for following condition as follows.
    a column has value as
    ALLOW
    TO ALL PERSON
    ALLOW ME
    in this i have check the following condition.
    excepted result:
    if i give
    REGEXP_LIKE(column_name,'ALL')
    Result:
    1 row selected
    if i give
    REGEXP_LIKE(column_name,'ALLOW THIS PERSON')
    Result:
    0 rows selected.
    Thanks & Regards
    Sami
    Edited by: Sami on Nov 2, 2010 6:08 PM
    Edited by: Sami on Nov 2, 2010 6:09 PM

    Please use the {noformat}{noformat}tag and post formatted data.
    For example, when you type (or copy/paste):
    {noformat}select *
    from dual;
    {noformat}
    it will appear as:select *
    from dual;
    on this forum.
    See for FAQ for more tags: http://forums.oracle.com/forums/help.jspa
    Regarding your question: what is your exect desired output? It's not 100% clear to me what you want.
    If I use your first 'example' I get three rows:SQL> -- generating sample data:
    SQL> with t as (
    2 select 'ALLOW' col from dual union
    3 select 'TO ALL PERSON' from dual union
    4 select 'ALLOW ME' from dual
    5 )
    6 --
    7 -- actueal query:
    8 --
    9 select col
    10 from t
    11 where regexp_like(col, 'ALL');
    COL
    ALLOW
    ALLOW ME
    TO ALL PERSON
    3 rows selected.

  • Query help using regexp_like

    kindly help me on this
    DECLARE
        STRING1  VARCHAR2(1000) :='NOT  (   VIP5';
        BEGIN
          if  regexp_like(string1 ,'NOT  \(* VIP5')  then
                 dbms_output.put_line('string1 is correct');
                     dbms_output.PUT_LINE(STRING1);
          end if;
        END;problem is STRING1 can be
    'NOT ( VIP5  '
       OR  can be                                   NOT     (          VIP5'ie between NOT AND VIP5 brackets will be there with spaces or without spaces
    so help me for the output
    S
    Edited by: oraclehema on Mar 1, 2011 3:38 AM

    HAI
    it is working
    using
    declare
         STRING1  VARCHAR2(1000) :='NOT    (      VIP5';
         STRING2  VARCHAR2(1000) :='NOT  (   (    (     VIP5';
         begin
        if REGEXP_LIKE( string2, 'NOT[[:space:]]*\([[:space:]]*\([[:space:]]*\([[:space:]]*VIP5')  then
         dbms_output.put_line('string2 is correct');
          dbms_output.PUT_LINE(STRING2);
          end if;
          end;Edited by: oraclehema on Mar 1, 2011 3:52 AM

  • Help with REGEXP_LIKE

    Hi, I am on oracle 11g release 1.
    I have the following requirement.
    I need to display data the following way from the column,
    One alphabet followed by 2 digits (like A00, B20, C12), I know I have to use REGEXP_LIKE, but i am not able to get the correct result.
    my first attempt at this is
    WITH t1
    as
    (select '01G50' investor_number from dual
      union all
      select 'A00' from dual
      union all
      select 'B20' from dual
      union all
      select '1234' from dual
    select investor_number from t1
    where  REGEXP_LIKE(investor_number, '[[:alpha:]]');
    but this gives
    investor_number
    01G50
    A00
    B20
    but I want only,
    investor_number
    A00
    B20how do i do that?
    Thanks
    Billu.

    Hi, Billu,
    If you only want to consider the letters that come at the beginning of the string, then anchor the pattern to the beginning of the string, like this:
    SELECT  investor_number
    FROM     t1
    WHERE     REGEXP_LIKE ( investor_number
                  , '^[[:alpha:]][[:digit:]]{2}'
    ;You could also write it this way, for clarity:
    SELECT  investor_number
    FROM     t1
    WHERE     REGEXP_LIKE ( investor_number
                  , '^'          || -- Right at the beginning of the string, there must be
                    '[[:alpha:]]'     || -- one letter, followed by
                    '[[:digit:]]{2}'        -- two numerals
    ;It doesn't matter what (if anything) comes after the 2 digits: another digit ('B209'), a letter ('B20XYZ'), any other character ('B20-9-XYZ'), or nothing (that is, the end-of-string) are all okay.
    If you want to find strings that contain only the pattern, and nothing after that, then anchor the patttern to the end-of-string ('$') also:
    SELECT  investor_number
    FROM     t1
    WHERE     REGEXP_LIKE ( investor_number
                  , '^'          || -- Right at the beginning of the string, there must be
                    '[[:alpha:]]'     || -- one letter, followed by
                    '[[:digit:]]{2}'     || -- two numerals, and then
                    '$'             -- the string must end
    ;Edited by: Frank Kulash on Sep 7, 2010 12:48 PM

  • Help with REGEXP_LIKE statement

    Hello Experts
    I am having little problem in solving the problem with REGEXP_LIKE as shown below.
    All the records are giving me the desired result except the last one where it has alph and numeric and spaces in between.
    Can I please have the solution please. I tried with INSTR but it didn't work too.
    Thanks in advance
    Rajesh
    WITH T AS
    (SELECT '000 444$888' STUDENT_ID FROM DUAL UNION ALL
    SELECT '^^^^^^^^^^ ' STUDENT_ID FROM DUAL UNION ALL
    SELECT 'ABCDEFGH&' STUDENT_ID FROM DUAL UNION ALL
    SELECT '!@@@@@@@ ' STUDENT_ID FROM DUAL UNION ALL
    SELECT '123456*891 ' STUDENT_ID FROM DUAL UNION ALL
    SELECT 'AAA 77BBBBB ' STUDENT_ID FROM DUAL
    SELECT student_id FROM T
    WHERE not REGEXP_LIKE(trim(STUDENT_ID), '^[[:alnum:]]*$')

    Rb2000rb65 wrote:
    Thanks Sven. But as you mentioned it did not solve my problem.My first two variants didn't work? Maybe you should start again and explaining which lines you want to see, which not and why.
    So far you only mentioned, that the last line gives you trouble. Whatever that means.
    /* this is your output */
    WITH T AS
    (SELECT '000 444$888' STUDENT_ID FROM DUAL UNION ALL
    SELECT '^^^^^^^^^^ ' STUDENT_ID FROM DUAL UNION ALL
    SELECT 'ABCDEFGH&' STUDENT_ID FROM DUAL UNION ALL
    SELECT '!@@@@@@@ ' STUDENT_ID FROM DUAL UNION ALL
    SELECT '123456*891 ' STUDENT_ID FROM DUAL UNION ALL
    SELECT 'AAA 77BBBBB ' STUDENT_ID FROM DUAL
    SELECT student_id FROM T
    WHERE not REGEXP_LIKE(trim(STUDENT_ID), '^[[:alnum:]]*$')
    000 444$888
    ^^^^^^^^^^
    ABCDEFGH&
    123456*891
    AAA 77BBBBB
    /* this is my output */
    WITH T AS
    (SELECT '000 444$888' STUDENT_ID FROM DUAL UNION ALL
    SELECT '^^^^^^^^^^ ' STUDENT_ID FROM DUAL UNION ALL
    SELECT 'ABCDEFGH&' STUDENT_ID FROM DUAL UNION ALL
    SELECT '!@@@@@@@ ' STUDENT_ID FROM DUAL UNION ALL
    SELECT '123456*891 ' STUDENT_ID FROM DUAL UNION ALL
    SELECT 'AAA 77BBBBB ' STUDENT_ID FROM DUAL
    SELECT student_id FROM T
    WHERE REGEXP_LIKE(STUDENT_ID, '[^[:alnum:] ]')
    000 444$888
    ^^^^^^^^^^
    ABCDEFGH&
    123456*891 As you can see the last line is missing now. I thought that is what you wanted?
    Edited by: Sven W. on Oct 12, 2012 6:42 PM

  • Help in regular expression matching

    I have three expressions like
    1) [(y2009)(y2011)]
    2) [(y2008M5)(y2011M3)] or [(y2009M5)(y2010M12)]
    3) [(y2009M1d20)(y2011M12d31)]
    i want regular expression pattern for the above three expressions
    I am using :
    REGEXP_LIKE(timedomainexpression, '???[:digit:]{4}*[:digit:]{1,2}???[:digit:]{4}*[:digit:]{1,2}??', 'i');
    but its giving results for all above expressions while i want different expression for each.
    i hav used * after [:digit:]{4}, when i am using ? or . then its giving no results. Please help in this situation ASAP.
    Thanks

    I dont get your question Can you post your desired output? and also give some sample data.
    Please consider the following when you post a question.
    1. New features keep coming in every oracle version so please provide Your Oracle DB Version to get the best possible answer.
    You can use the following query and do a copy past of the output.
    select * from v$version 2. This forum has a very good Search Feature. Please use that before posting your question. Because for most of the questions
    that are asked the answer is already there.
    3. We dont know your DB structure or How your Data is. So you need to let us know. The best way would be to give some sample data like this.
    I have the following table called sales
    with sales
    as
          select 1 sales_id, 1 prod_id, 1001 inv_num, 120 qty from dual
          union all
          select 2 sales_id, 1 prod_id, 1002 inv_num, 25 qty from dual
    select *
      from sales 4. Rather than telling what you want in words its more easier when you give your expected output.
    For example in the above sales table, I want to know the total quantity and number of invoice for each product.
    The output should look like this
    Prod_id   sum_qty   count_inv
    1         145       2 5. When ever you get an error message post the entire error message. With the Error Number, The message and the Line number.
    6. Next thing is a very important thing to remember. Please post only well formatted code. Unformatted code is very hard to read.
    Your code format gets lost when you post it in the Oracle Forum. So in order to preserve it you need to
    use the {noformat}{noformat} tags.
    The usage of the tag is like this.
    <place your code here>\
    7. If you are posting a *Performance Related Question*. Please read
       {thread:id=501834} and {thread:id=863295}.
       Following those guide will be very helpful.
    8. Please keep in mind that this is a public forum. Here No question is URGENT.
       So use of words like *URGENT* or *ASAP* (As Soon As Possible) are considered to be rude.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   

  • Query help in regular expression

    Hi all,
    SELECT * FROM emp11
    WHERE INSTR(ENAME,'A',1,2) >0;
    Please let me know the equivalent query using regular expressions.
    i have tried this after going through oracle regular expressions documentation.
    SELECT * FROM emp11
    WHERE regexp_LIKE(ename,'A{2}')
    Any help in this regard would be highly appreciated .
       Thanks,
    P Prakash

    please go here
    Introduction to regular expressions ...
    Thanks,
    P Prakash

  • Help With Regular Expression In Apex Validation

    Apex 3.2
    There is a validation type of regular expression in apex, but I have never used regular expression before,
    so a little help is appreciated.
    I need to validate a field. It is only allowed to contain alpha characers, numbers, spaces and the - (dash) character.
    I have tried several times to get this working
    eg
    [[:alpha:]]*[[:digit:]]*[[:space:]]*[-]*
    ^[[:alpha:][:digit:][:space:]-]+?
    and others, but just can't to get the syntax correct.
    Can someone help me with this please
    Gus

    Example:
    SQL> ed
    Wrote file afiedt.buf
      1  with t as (select 'This is some example text' as txt from dual union all
      2             select 'And this is the 2nd one with numbers' from dual union all
      3             select 'And this allows double-barrelled words with hyphens' from dual union all
      4             select 'But this one shouldn''t be allowed!' from dual
      5            )
      6  --
      7  select *
      8  from t
      9* where regexp_like(txt, '^[[:alnum:] -]*$')
    SQL> /
    TXT
    This is some example text
    And this is the 2nd one with numbers
    And this allows double-barrelled words with hyphens

  • Code Search HELP

    Here is my situation. I have a table that has a list of codes almost 100K. I have another table that has code listed in term of an in house regular expression.
    Example:
    40a.[1,2,3]
    12b
    Where
    a is 0 - 9
    b is 1 - 9
    I have tried using REGEXP_LIKE but I get ORA-04030: out of process memory error.
    My question is there a way to do this search such that it will be fast and efficient.
    I have through about expanding the Expressed code, but that could lead to a lot of codes, and it specially gets tricky if the code is in the format of "1a2b". In this case I would need to somehow create 90 (10*9) rows. I am not entriely sure how to do this dynamically, because there could be a lot of variations.
    The current approcach I am thinking of is to search based on character placement. Such that each character becomes a column and I do the comparisson as
    Base_Char_1 = Code_Exp_1
    Base_Char_2 = Code_Exp_2
    I have not figured out how this would work. Shown below is the REGEXP_LIKE approach. Any help or advice would be great.
    WITH t1 AS
         (SELECT '40a.[0,1,9]1' AS code_exp
            FROM DUAL
         ), t2 AS
           (SELECT code_exp
                 , '^' || REPLACE (REPLACE (REPLACE (REPLACE (code_exp, 'a', '[0-9]'), '.', '\.'), 'b', '[1-9]'), ',') || '$' AS code_regexp
              FROM t1)
    SELECT *
      FROM t2
    WHERE REGEXP_LIKE ('402.11', code_regexp)Thanks.

    Well, it is probably a design issue - joining 100 000 codes with 10 000 regular expressions based on regexp_like() will effectively mean 1e9 calculated regular expressions, which means a lot of work i suppose.
    Besides that, there is indeed something strange on pga/uga memory consumption when regular expressions are stored in the table. I've set up small test case based on your data
    SQL> CREATE TABLE codes AS
      2  SELECT dbms_random.string('p',10) code
      3  FROM dual
      4  CONNECT BY LEVEL <=100000
      5  UNION ALL
      6  SELECT '402.11' FROM dual
      7  /
    Table created.
    SQL> CREATE TABLE code_expressions AS
      2  WITH t1 AS
      3  (SELECT '40a.[0,1,9]1' AS code_exp
      4          FROM DUAL
      5  ), t2 AS
      6  (SELECT code_exp, '^' ||
      7          REPLACE (REPLACE (REPLACE (REPLACE (code_exp, 'a', '[0-9]'), '.', '\.'), 'b', '[1-9]'), ',')
      8          || '$' AS code_regexp
      9          FROM t1)
    10  SELECT * FROM t2
    11  /
    Table created.
    SQL> exec dbms_stats.gather_table_stats(user,'codes')
    PL/SQL procedure successfully completed.
    SQL> exec dbms_stats.gather_table_stats(user,'code_expressions')
    PL/SQL procedure successfully completed.
    SQL> set lines 100
    SQL> col code for a15
    SQL> col code_exp for a15
    SQL> col code_regexp for a25
    SQL> exec runStats_pkg.rs_start;
    PL/SQL procedure successfully completed.
    SQL> SELECT * FROM codes,code_expressions WHERE regexp_like(code,'^40[0-9]\.[019]1$');
    CODE            CODE_EXP        CODE_REGEXP
    402.11          40a.[0,1,9]1    ^40[0-9]\.[019]1$
    SQL> exec runStats_pkg.rs_middle;
    PL/SQL procedure successfully completed.
    SQL> SELECT * FROM codes,code_expressions WHERE regexp_like(code,code_regexp);
    CODE            CODE_EXP        CODE_REGEXP
    402.11          40a.[0,1,9]1    ^40[0-9]\.[019]1$
    SQL> exec runStats_pkg.rs_stop;
    Run1 ran in 34 hsecs
    Run2 ran in 276 hsecs
    run 1 ran in 12.32% of the time
    Name                                  Run1        Run2        Diff
    STAT...session cursor cache co           1           0          -1
    .... sniped
    STAT...CPU used when call star          37         276         239
    STAT...CPU used by this sessio          37         276         239
    STAT...DB time                          37         277         240
    STAT...Elapsed Time                     36         283         247
    STAT...session pga memory           65,536           0     -65,536
    STAT...session uga memory           65,560           0     -65,560
    STAT...session pga memory max      262,144  10,551,296  10,289,152
    STAT...session uga memory max      261,964  10,592,024  10,330,060
    Run1 latches total versus runs -- difference and pct
            Run1        Run2        Diff       Pct
           1,009       1,348         339     74.85%
    PL/SQL procedure successfully completed.
    SQL>
    SQL> conn scott/tiger
    Connected.
    SQL> set lines 100
    SQL> col code for a15
    SQL> col code_exp for a15
    SQL> col code_regexp for a25
    SQL>
    SQL> exec runStats_pkg.rs_start;
    PL/SQL procedure successfully completed.
    SQL> SELECT * FROM codes,code_expressions WHERE regexp_like(code,'^40[0-9]\.[019]1$');
    CODE            CODE_EXP        CODE_REGEXP
    402.11          40a.[0,1,9]1    ^40[0-9]\.[019]1$
    SQL> exec runStats_pkg.rs_middle;
    PL/SQL procedure successfully completed.
    SQL> SELECT * FROM codes,code_expressions
      2  WHERE regexp_like(code,'^' ||
      3  REPLACE (REPLACE (REPLACE (REPLACE (code_exp, 'a', '[0-9]'), '.', '\.'), 'b', '[1-9]'), ',') ||
      4           '$');
    CODE            CODE_EXP        CODE_REGEXP
    402.11          40a.[0,1,9]1    ^40[0-9]\.[019]1$
    SQL> exec runStats_pkg.rs_stop;
    Run1 ran in 37 hsecs
    Run2 ran in 335 hsecs
    run 1 ran in 11.04% of the time
    Name                                  Run1        Run2        Diff
    STAT...recursive cpu usage               3           2          -1
    .... sniped
    STAT...CPU used when call star          40         336         296
    STAT...CPU used by this sessio          40         336         296
    STAT...DB time                          40         336         296
    STAT...Elapsed Time                     39         338         299
    STAT...session pga memory           65,536           0     -65,536
    STAT...session uga memory           65,560           0     -65,560
    STAT...session pga memory max      262,144  10,551,296  10,289,152
    STAT...session uga memory max      261,964  10,592,024  10,330,060
    Run1 latches total versus runs -- difference and pct
            Run1        Run2        Diff       Pct
           1,022       1,348         326     75.82%
    PL/SQL procedure successfully completed.
    SQL> explain plan for
      2  SELECT * FROM codes,code_expressions WHERE regexp_like(code,'^40[0-9]\.[019]1$');
    Explained.
    SQL> select * from table(dbms_xplan.display);
    PLAN_TABLE_OUTPUT
    Plan hash value: 1698472622
    | Id  | Operation            | Name             | Rows  | Bytes | Cost (%CPU)| Time     |
    |   0 | SELECT STATEMENT     |                  |  5000 |   205K|    59   (6)| 00:00:01 |
    |   1 |  MERGE JOIN CARTESIAN|                  |  5000 |   205K|    59   (6)| 00:00:01 |
    |   2 |   TABLE ACCESS FULL  | CODE_EXPRESSIONS |     1 |    31 |     3   (0)| 00:00:01 |
    |   3 |   BUFFER SORT        |                  |  5000 | 55000 |    56   (6)| 00:00:01 |
    |*  4 |    TABLE ACCESS FULL | CODES            |  5000 | 55000 |    56   (6)| 00:00:01 |
    Predicate Information (identified by operation id):
       4 - filter( REGEXP_LIKE ("CODE",'^40[0-9]\.[019]1$'))
    16 rows selected.
    SQL> explain plan for
      2  SELECT * FROM codes,code_expressions WHERE regexp_like(code,code_regexp);
    Explained.
    SQL> select * from table(dbms_xplan.display);
    PLAN_TABLE_OUTPUT
    Plan hash value: 3098457583
    | Id  | Operation          | Name             | Rows  | Bytes | Cost (%CPU)| Time     |
    |   0 | SELECT STATEMENT   |                  |  5000 |   205K|    57   (2)| 00:00:01 |
    |   1 |  NESTED LOOPS      |                  |  5000 |   205K|    57   (2)| 00:00:01 |
    |   2 |   TABLE ACCESS FULL| CODE_EXPRESSIONS |     1 |    31 |     3   (0)| 00:00:01 |
    |*  3 |   TABLE ACCESS FULL| CODES            |  5000 | 55000 |    54   (2)| 00:00:01 |
    Predicate Information (identified by operation id):
       3 - filter( REGEXP_LIKE ("CODE","CODE_REGEXP"))
    15 rows selected.
    SQL> explain plan for
      2  SELECT * FROM codes,code_expressions WHERE regexp_like(code,'^' ||
      3  REPLACE (REPLACE (REPLACE (REPLACE (code_exp, 'a', '[0-9]'), '.', '\.'), 'b', '[1-9]'), ',') ||'$');
    Explained.
    SQL> select * from table(dbms_xplan.display);
    PLAN_TABLE_OUTPUT
    Plan hash value: 3098457583
    | Id  | Operation          | Name             | Rows  | Bytes | Cost (%CPU)| Time     |
    |   0 | SELECT STATEMENT   |                  |  5000 |   205K|    57   (2)| 00:00:01 |
    |   1 |  NESTED LOOPS      |                  |  5000 |   205K|    57   (2)| 00:00:01 |
    |   2 |   TABLE ACCESS FULL| CODE_EXPRESSIONS |     1 |    31 |     3   (0)| 00:00:01 |
    |*  3 |   TABLE ACCESS FULL| CODES            |  5000 | 55000 |    54   (2)| 00:00:01 |
    Predicate Information (identified by operation id):
       3 - filter( REGEXP_LIKE ("CODE",'^'||REPLACE(REPLACE(REPLACE(REPLACE("CODE_E
                  XP",'a','[0-9]'),'.','\.'),'b','[1-9]'),',')||'$'))
    16 rows selected.Best regards
    Maxim

  • Small Query help

    small query i have data like below ,
    Month ProductNo CustomerNo     Units
    Jan 9001 1001-09 100
    jan 9002 1002-09 200
    jan 9003 1003-09 300
    jan 9001 ABCCustomer 400
    Jan 9002 1004-09 500
    for any record - if column - customerNo starts with numeric it has to show like CN_****** other wise the same name.
    Result should be
    Jan 9001 CN_1001-09 100
    jan 9002 CN_1002-09 200
    jan 9003 CN_1003-09 300
    jan 9001 ABCCustomer 400
    Jan 9002     CN_1004-09 500
    Can some one help to get the query

    Hi,
    try this,
    SQL>  select *from v$version;
    BANNER
    Personal Oracle Database 10g Release 10.1.0.2.0 - Production
    PL/SQL Release 10.1.0.2.0 - Production
    CORE    10.1.0.2.0      Production
    TNS for 32-bit Windows: Version 10.1.0.2.0 - Production
    NLSRTL Version 10.1.0.2.0 - Production
      1  with t  as
      2  (select 'Jan' Month ,9001 ProductNo, '1001-09' CustomerNo, 100 Units from dual
      3  union all
      4  select 'jan', 9002 ,'1002-09', 200 from dual
      5  union all
      6  select 'jan', 9003, '1003-09', 300 from dual
      7  union all
      8  select 'jan', 9001, 'ABCCustomer', 400 from dual
      9  union all
    10  select 'Jan', 9002, '1004-09', 500  from dual)
    11  select  Month,ProductNo,(case when regexp_like(customerno,'^[[:digit:]]') then
    12   'CN_'||CustomerNo
    13  else
    14* CustomerNo end)cudtomer_no, units from t
    SQL> /
    MON  PRODUCTNO CUDTOMER_NO         UNITS
    Jan       9001 CN_1001-09            100
    jan       9002 CN_1002-09            200
    jan       9003 CN_1003-09            300
    jan       9001 ABCCustomer           400
    Jan       9002 CN_1004-09            500or
    regexp_like(customerno,'^[0-9]')or
    regexp_like(customerno,'^[0123456789]')Edited by: user291283 on Sep 12, 2009 8:22 AM
    Edited by: user291283 on Sep 12, 2009 9:24 AM

  • Need Help with instr/Regexp for the query

    Hi Oracle Folks
    I am using Oracle
    Oracle Database 11g Enterprise Edition Release 11.1.0.7.0 - 64bit Production
    With the Partitioning, OLAP, Data Mining and Real Application Testing options
    I have some student responses and the valid values are +/-/O(alphabet)/P and spaces at the end of the sting only not in the middle.
    As per my requirement the record number 2 3,4 should be listed from the query but I am getting only one (record 3).
    Can we use REG_EXP
    Please help.
    Thanks in advance.
    Rajesh
    with x as (
    SELECT '+-+-POPPPPPP   ' STUDENT_RESPONSE, 1 record_number FROM DUAL union all
    SELECT '+--AOPPPPPP++' STUDENT_RESPONSE, 2 record_number FROM DUAL union all
    SELECT '+-+-  OPPPPPP--' STUDENT_RESPONSE, 3 record_number FROM DUAL union all
    SELECT '+-+-9OPPPPPP   ' STUDENT_RESPONSE, 4 record_number FROM DUAL )
    (SELECT RECORD_NUMBER,
    TRIM(STUDENT_RESPONSE) FROM X
    WHERE
    ((INSTR (UPPER(TRIM(STUDENT_RESPONSE)),'-') =0)
    OR (INSTR (UPPER(TRIM(STUDENT_RESPONSE)),'+') =0)
    OR (INSTR (UPPER(TRIM(STUDENT_RESPONSE)),'O') =0)
    OR (INSTR (UPPER(TRIM(STUDENT_RESPONSE)),'P') =0)
    OR (INSTR (UPPER(TRIM(STUDENT_RESPONSE)),' ') !=0)
    )

    Hi, Rajesh,
    Rb2000rb65 wrote:
    Hi Oracle Folks
    I am using Oracle
    Oracle Database 11g Enterprise Edition Release 11.1.0.7.0 - 64bit Production
    With the Partitioning, OLAP, Data Mining and Real Application Testing optionsThanks for posting this (and the WITH clause for the sample data). That's very helpful.
    I have some student responses and the valid values are +/-/O(alphabet)/P and spaces at the end of the sting only not in the middle.Are you combining the responses to several qeustions in one VARCHAR2 column? It might be better to have a separate row for each question.
    As per my requirement the record number 2 3,4 should be listed from the query but I am getting only one (record 3). What exactly is your requirement? Are you trying to find the rows where student_response contains any of the forbidden characters, or where it contains a space anywhere but at the end of the string?
    Can we use REG_EXPYes, but it's easy enough, and probably more efficient, to not use regular expressions in this case:
    Here's one way:
    SELECT     record_number
    ,     student_response
    FROM     x
    WHERE     TRANSLATE ( UPPER ( RTRIM (student_response, ' '))
                , 'X+-OP'
                , 'X'
                )     IS NOT NULL
    ;That is, once you remove trailing spaces and all occurrences of '+', '-', 'O' or 'P', then only the forbidden characters are left, and you want to select the row if there are any of those.
    If you really, really want to use a regular expression:
    SELECT     record_number
    ,     student_response
    FROM     x
    WHERE     REGEXP_LIKE ( RTRIM (student_response)
                  , '[^-+OP]'          -- or '[^+OP-]', but not '[^+-OP]'.  Discuss amongst yourselves
                  , 'i'
    ;but, I repeat, this will probably be slower than the first solution, using TRANSLATE.
    Edited by: Frank Kulash on Oct 17, 2011 1:05 PM
    Edited by: Frank Kulash on Oct 17, 2011 1:41 PM
    The following is slightly simpler than TRANSLATE:
    SELECT     record_number
    ,     student_response
    FROM     x
    WHERE     RTRIM ( UPPER ( RTRIM (student_response, ' '))
               , '+-OP'
               )          IS NOT NULL
    ;

Maybe you are looking for