Split a VARCHAR in DB2 to retrieve a value inside

后端 未结 5 605
我在风中等你
我在风中等你 2020-12-10 06:40

I have a VARCHAR column that contains 5 informations (2 CHAR(3) and 3 TIMESTAMP) separated with \'$\'.

C         


        
相关标签:
5条回答
  • 2020-12-10 06:49

    If your DB2's version can do it, you can use then LOCATE_IN_STRING function for to found position of your separator. The LOCATE_IN_STRING function returns the starting position of a string and enable you to choice the Nth instance. You can found documentation of this function here

    For your example, you can use this code :

    select 
    substring(col, LOCATE_IN_STRING(col, '$', 1, 3), LOCATE_IN_STRING(col, '$', 1, 4) - LOCATE_IN_STRING(col, '$', 1, 3))                       
    from MYTABLE                                            
    
    0 讨论(0)
  • 2020-12-10 06:54
       substr(e.data,1,13) as NNSS,
       substring(e.data, LOCATE_IN_STRING(e.data, ';', 1, 1, CODEUNITS32)+1,  (LOCATE_IN_STRING(e.data, ';', 1, 2, CODEUNITS32) - LOCATE_IN_STRING(e.data, ';', 1, 1, CODEUNITS32)-1) ) as Name,  
       substring(e.data, LOCATE_IN_STRING(e.data, ';', 1, 2, CODEUNITS32)+1,  (LOCATE_IN_STRING(e.data, ';', 1, 3, CODEUNITS32) - LOCATE_IN_STRING(e.data, ';', 1, 2, CODEUNITS32)-1) ) as Vorname,
       substring(e.data, LOCATE_IN_STRING(e.data, ';', 1, 3, CODEUNITS32)+1,  (LOCATE_IN_STRING(e.data, ';', 1, 4, CODEUNITS32) - LOCATE_IN_STRING(e.data, ';', 1, 3, CODEUNITS32)-1) ) as Grund
    
    0 讨论(0)
  • 2020-12-10 06:58
    CREATE FUNCTION split(pos INT, delimeter CHAR, string VARCHAR(255))
    LANGUAGE SQL
    RETURNS VARCHAR(255)
    DETERMINISTIC NO EXTERNAL ACTION
    BEGIN ATOMIC
        DECLARE x INT;
        DECLARE s INT;
        DECLARE e INT;
    
        SET x = 0;
        SET s = 0;
        SET e = 0;
    
        WHILE (x < pos) DO
            SET s = locate(delimeter, string, s + 1);
            IF s = 0 THEN
                RETURN NULL;
            END IF;
            SET x = x + 1;
        END WHILE;
    
        SET e = locate(delimeter, string, s + 1);
        IF s >= e THEN
            SET e = LENGTH(string) + 1;
        END IF;
        RETURN SUBSTR(string, s + 1, e - s -1);
    END!
    

    Usage:

    SELECT split(3,'$',col) from mytable; -- or
    SELECT split(0,'-', 'first-second-third') from sysibm.sysdummy1;
    SELECT split(0,'-', 'returns this') from sysibm.sysdummy1;
    SELECT split(1,'-', 'returns null') from sysibm.sysdummy1;
    
    0 讨论(0)
  • 2020-12-10 07:05

    I am sure there is a better way to write this, but here is 1 (SQL) solution for the simple case given. It could be rewritten as a stored procedure to look for any arbitrary string. There may also be some 3rd party tools/extensions to help out w/ the split you want...

    select
    locate('$', col, (locate('$',col, (locate('$',col) +1))) + 1) as poss3rdDollarSign, -- position of 3rd dollar sign
    locate('$', col, (locate('$', col, (locate('$',col, (locate('$',col) +1))) + 1)) + 1) as poss4thDollarSign, -- position of 4th dollar sign
        (locate('$', col, (locate('$', col, (locate('$',col, (locate('$',col) +1))) + 1)) + 1)) - 
        (locate('$', col, (locate('$',col, (locate('$',col) +1))) + 1)) - 1  as stringLength,-- length of string between 3rd and 4th dollar sign
        substr(col, locate('$', col, (locate('$',col, (locate('$',col) +1))) + 1)  + 1, (locate('$', col, (locate('$', col, (locate('$',col, (locate('$',col) +1))) + 1)) + 1)) - 
        (locate('$', col, (locate('$',col, (locate('$',col) +1))) + 1)) - 1) as string
        from mytable
    
    0 讨论(0)
  • 2020-12-10 07:11

    try this, it works!

    CREATE FUNCTION SPLIT( P_1 VARCHAR(3200),
                           P_2 VARCHAR(200))
        RETURNS TABLE(P_LIST VARCHAR(3200))
        SPECIFIC SPLIT
        LANGUAGE SQL
        MODIFIES SQL DATA
        NO EXTERNAL ACTION
    F1: BEGIN
        return
        with source(str, del) as
            (select p_1, p_2 from sysibm.sysdummy1),
                target(str, del) as
                (select source.str, source.del from source
                    where length(source.str) > 0
             union all
                select 
                (case when (instr(target.str, target.del) > 0) 
                                        then substr(target.str, 
                                                     instr(target.str, target.del)+1, 
                                                       length(target.str)-instr(target.str, target.del))                                  else null end),
                    (case when (instr(target.str, target.del) > 0) 
                                                  then target.del else null end)
                    from target
                    where length(target.str) > 0
                    )
            select str from target
            where str is not null;
    END
    
    0 讨论(0)
提交回复
热议问题