0

I have the following dataset:

Ident Script
ID1 Var_xxx_calc + Var_yyy_db + Var_zzz_calc
ID2 Var_xxx_calc + Var_zzz_db

Is there any way to split this up into the following table?

Ident Script Var1 Var2 Var3
ID1 Var_xxx_calc + Var_yyy_db + Var_zzz_calc Var_xxx_calc Var_yyy_db Var_zzz_calc
ID2 if Var_xxx_calc + Var_zzz_db > 10 then 'OK' else 'NOK' Var_xxx_calc Var_zzz_db null

Extra difficulty: the Var_% all have different lengths, I only know they start with 'Var_'

I use Oracle Production version 19.12.0.0.0

2
  • Can you please elaborate it more? You want dynamic table or just want to find the length of script column or find the number of '+' strings? Commented Jul 28, 2022 at 15:19
  • They start with var_% but is there any delimiter or pattern? For example; Var_% whitespace(special character like "+" or ">")whitespaceVar_% . Commented Jul 28, 2022 at 22:51

2 Answers 2

0

Tried to find a solution and ended with a limited one. I use a delimiter that is forcefully implanted into the SCRIPT instead of any possible character that could be infront of or just after your 'Var_something' string. You will see it in code as "endless" Replaces. The idea is to set a delimiter if it is posssible just after the string you are trying to separate.
Here is the code with some sample data generaated by WITH clause:

WITH
    tbl AS
        (
            Select 'ID_1' "IDENT", 'Var_xxxxx_calculus + Var_yyy_dbase + Var_zz_calc' "SCRIPT" From Dual Union All
            Select 'ID_2' "IDENT", 'Var_xxxxx_calcul + Var_yyy_dbase' "SCRIPT" From Dual Union All
            Select 'ID_3' "IDENT", 'If Var_xxx_calc + Var_zzz_db* 2 > 10 then "OK" else "NOK"' "SCRIPT" From Dual Union All
            Select 'ID_4' "IDENT", 'Some other text without Var followed by underscore' "SCRIPT" From Dual Union All
            Select 'ID_5' "IDENT", 'And some with "Var_"  Var_A, Var_B, Var_C in it' "SCRIPT" From Dual
        )
SELECT
    IDENT "IDENT",
    SCRIPT "SCRIPT",
    CASE 
        WHEN VAR_COUNT > 0 THEN 
            SubStr( SCRIPT_DELIMITED, 
                    InStr(SCRIPT_DELIMITED, 'Var_', 1, 1), 
                    InStr(SCRIPT_DELIMITED, ';', InStr(SCRIPT_DELIMITED, 'Var_', 1, 1), 1) - InStr(SCRIPT_DELIMITED, 'Var_', 1, 1) 
                  ) 
    END "VAR_1",
    CASE 
        WHEN VAR_COUNT > 1 THEN 
            SubStr( SCRIPT_DELIMITED, 
                    InStr(SCRIPT_DELIMITED, 'Var_', 1, 2), 
                    InStr(SCRIPT_DELIMITED, ';', InStr(SCRIPT_DELIMITED, 'Var_', 1, 2), 1) - InStr(SCRIPT_DELIMITED, 'Var_', 1, 2) 
                  ) 
    END "VAR_2",
    CASE 
        WHEN VAR_COUNT > 2 THEN 
            SubStr( SCRIPT_DELIMITED, 
                    InStr(SCRIPT_DELIMITED, 'Var_', 1, 3), 
                    InStr(SCRIPT_DELIMITED, ';', InStr(SCRIPT_DELIMITED, 'Var_', 1, 3), 1) - InStr(SCRIPT_DELIMITED, 'Var_', 1, 3) 
                  ) 
    END "VAR_3",
    CASE 
        WHEN VAR_COUNT > 3 THEN 
            SubStr( SCRIPT_DELIMITED, 
                    InStr(SCRIPT_DELIMITED, 'Var_', 1, 4), 
                    InStr(SCRIPT_DELIMITED, ';', InStr(SCRIPT_DELIMITED, 'Var_', 1, 4), 1) - InStr(SCRIPT_DELIMITED, 'Var_', 1, 4) 
                  ) 
    END "VAR_4"
FROM
    (
        SELECT
          IDENT "IDENT",
          SCRIPT "SCRIPT",
          CASE 
                WHEN InStr(SCRIPT, 'Var_', 1, 4) > 0 THEN 4
                WHEN InStr(SCRIPT, 'Var_', 1, 3) > 0 THEN 3
                WHEN InStr(SCRIPT, 'Var_', 1, 2) > 0 THEN 2
                WHEN InStr(SCRIPT, 'Var_', 1, 1) > 0 THEN 1
          ELSE 0
          END "VAR_COUNT",
          Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(SCRIPT, ' ', ';'), '+', ';'), '>', ';'), '<', ';'), '=', ';'), '"', ';'), '*', ';'), ',', ';') || ';' "SCRIPT_DELIMITED"
        FROM
            tbl
    )

It is limited here with four variables selected for separation and with a condition that there is no other separation character than those treated with Replace functions.
The result with sample data is:

--  IDENT SCRIPT                                                    VAR_1                                                      VAR_2                                                      VAR_3                                                      VAR_4                                                    
--  ----- --------------------------------------------------------- ---------------------------------------------------------- ---------------------------------------------------------- ---------------------------------------------------------- ----------------------------------------------------------
--  ID_1  Var_xxxxx_calculus + Var_yyy_dbase + Var_zz_calc          Var_xxxxx_calculus                                         Var_yyy_dbase                                              Var_zz_calc                                                                                                           
--  ID_2  Var_xxxxx_calcul + Var_yyy_dbase                          Var_xxxxx_calcul                                           Var_yyy_dbase                                                                                                                                                                    
--  ID_3  If Var_xxx_calc + Var_zzz_db* 2 > 10 then "OK" else "NOK" Var_xxx_calc                                               Var_zzz_db                                                                                                                                                                       
--  ID_4  Some other text without Var followed by underscore                                                                                                                                                                                                                                                    
--  ID_5  And some with "Var_"  Var_A, Var_B, Var_C in it           Var_                                                       Var_A                                                      Var_B                                                      Var_C 

Regards...

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

Comments

0

Here's a solution using REGEXP_SUBSTR(). In the WITH clause, the 'tbl' table just sets up sample data from your original post. The select gets the first, second and third occurances of the pattern 'Var_', followed by one or more non-greedy characters, another underscore, another set of one or more non-greedy characters, where followed by a space and a character OR the end of the line. If the Var value could only contain alpha characters it would be better to specify that in order to tighten up the match and not risk including accidental values.

Caveat: It only selects 3 values per your original post.

WITH tbl(ident, script) AS (
  SELECT 'ID1', 'Var_xxx_calc + Var_yyy_db + Var_zzz_calc' FROM dual UNION ALL
  SELECT 'ID2', 'Var_xxx_calc + Var_zzz_db' FROM dual UNION ALL
  SELECT 'ID3', 'Var_xxx_calc + Var_yyy_db + Var_zzz_calc' FROM dual UNION ALL
  SELECT 'ID4', 'IF Var_xxx_calc + Var_zzz_db > 10 THEN ''OK'' ELSE ''NOK''' FROM dual
)
SELECT ident, 
       REGEXP_SUBSTR(script, '(Var_.+?_.+?)( .|$)', 1, 1, NULL, 1) AS Var1,
       REGEXP_SUBSTR(script, '(Var_.+?_.+?)( .|$)', 1, 2, NULL, 1) AS Var2,
       REGEXP_SUBSTR(script, '(Var_.+?_.+?)( .|$)', 1, 3, NULL, 1) AS Var3
FROM tbl;


IDENT VAR1            VAR2            VAR3           
----- --------------- --------------- ---------------
ID1   Var_xxx_calc    Var_yyy_db      Var_zzz_calc   
ID2   Var_xxx_calc    Var_zzz_db                     
ID3   Var_xxx_calc    Var_yyy_db      Var_zzz_calc   
ID4   Var_xxx_calc    Var_zzz_db                     

4 rows selected.

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.