9
votes

Diviser un varchar dans db2 pour récupérer une valeur à l'intérieur

J'ai une colonne code> varchar code> contenant 5 informations (2 char (3) code> et 3 horodatage code>) séparé avec ' $ code> '. xxx pré>

Je voudrais extraire le 4ème champ ... p> xxx pré>

... pour avoir quelque chose comme p>

SELECT SPLIT(COL, '$', 4) FROM MYTABLE

1
-----
'null'
'null'
'2009-04-10 10:50:00'


0 commentaires

5 Réponses :


4
votes

Je suis sûr qu'il y a une meilleure façon d'écrire cela, mais voici une solution de 1 (SQL) pour le cas simple donné. Il pourrait être réécrit comme une procédure stockée pour rechercher une chaîne arbitraire. Il peut également y avoir des outils / extensions tiers pour aider avec la scission que vous souhaitez ...

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


3 commentaires

+1 pour l'effort :-). J'ai aussi fini par faire quelque chose de similaire, mais je cherche quelque chose de plus générique .


C'est affreux, mais c'était exactement ce dont j'avais besoin pour m'aider à analyser de la chaîne dans une requête. Merci!


Merci pour la fonction de localisation. A contribué à une autre chaîne d'analyse de la chaîne, je devais convertir un Varchar avec: USD à la fin de celui-ci à un décalage.



7
votes
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;

2 commentaires

L'accepter, car c'est exactement ce que j'ai cherché (3ème option). Pouvez-vous simplement ajouter le déterministe et le modificateur d'action externe , pour pouvoir l'utiliser dans un groupe Groupe par Clause?


Bon point. Changé pour renvoyer NULL lorsque l'élément n'est pas trouvé. Demander le premier élément, avec non-existant-Deliemeter, retournera la chaîne d'origine.



1
votes

Essayez ceci, cela fonctionne!

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


1 commentaires

Quelle est la différence entre votre réponse et les précédents?



0
votes

Si la version de votre DB2 peut le faire, vous pouvez utiliser la fonction Locate_IN_String pour trouver la position de votre séparateur. La fonction locate_in_string renvoie la position de départ d'une chaîne et vous permet de choisir la nième instance. Vous pouvez trouver une documentation de cette fonction ici

pour Votre exemple, vous pouvez utiliser ce code: xxx


0 commentaires

0
votes
   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 commentaires