2017-06-12 5 views
0
IPCIDR       FLAG_V6 
-------------------------------- ---------- 
58.97.1.12/30     
58.97.1.16/30     
58.97.1.96/30     
58.97.1.100/30     
58.97.1.116/30     
2001:fb0:1061:99:0:0:0:0 /64  1 
2001:fb0:1061:9a:0:0:0:0 /64  1 
2001:fb0:1061:9f:0:0:0:0 /64  1 
2001:fb0:1061:a2:0:0:0:0 /64  1 

Je veux trier ipv4Comment trier adresses IPv4 et IPv6 dans les 1 colonne

order by (to_number(substr(ipcidr,1,instr(ipcidr,'.')-1)) 
, to_number(substr(ipcidr,instr(ipcidr,'.')+1, instr(ipcidr,'.',1,2) - instr(ipcidr,'.') - 1)) 
, to_number(substr(ipcidr,instr(ipcidr,'.',1,2)+1, instr(ipcidr,'.',1,3) - instr(ipcidr,'.',1,2) - 1)) 
, to_number(substr(ipcidr,instr(ipcidr,'.',1,3)+1,instr(ipcidr,'/')-instr(ipcidr,'.',1,3) - 1)) 
, to_number(substr(ipcidr,instr(ipcidr,'/')+1))) 

et trier IPV6 dans un Colum et je colonne FLAG_V6 si ipv6 set 1 autre null

+1

[S'il vous plaît ne pas poster des images lorsque vous pouvez nous montrer du texte formaté à la place] (https://meta.stackoverflow.com/questions/285551/pourquoi-ne-pas-télécharger-images-de-code-sur-donc-quand-posant-une-question/285557 # 285557). –

Répondre

1

Vous peut utiliser cette fonction pour traduire l'adresse IP en un nombre entier:

-- Convert a binary/octal/hex number into a decimal value 
CREATE FUNCTION Base2Dec(BaseString IN VARCHAR2, Base IN PLS_INTEGER DEFAULT 16) RETURN NUMBER DETERMINISTIC IS 

    BaseNumber NUMBER := 0; 
    HexString CONSTANT CHAR(16) := 'ABCDEF'; 

BEGIN 
    IF BaseString IS NULL THEN 
     RETURN NULL; 
    ELSIF Base NOT IN (2, 8, 16) THEN 
     RAISE VALUE_ERROR; 
    ELSIF Base = 16 THEN 
     RETURN TO_NUMBER(BaseString, 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'); 
    ELSE 
     FOR i IN 1..LENGTH(BaseString) LOOP 
      BaseNumber := BaseNumber * Base + INSTR(HexString, UPPER(SUBSTR(BaseString, i, 1))) - 1; 
     END LOOP; 
     RETURN BaseNumber; 
    END IF; 
END Base2Dec; 

CREATE FUNCTION UncompressIpV6(Ip IN VARCHAR2) RETURN VARCHAR2 DETERMINISTIC IS 
    IpFull VARCHAR2(40); 
BEGIN 
    IF REGEXP_LIKE(Ip, '::') THEN 
     IpFull := REGEXP_REPLACE(REGEXP_REPLACE(Ip, '^::', '0::'), '::$', '::0'); 
     WHILE REGEXP_COUNT(IpFull, ':') <= 7 LOOP 
      IpFull := REGEXP_REPLACE(IpFull, '::', ':0::'); 
     END LOOP; 
     RETURN REGEXP_REPLACE(IpFull, '::', ':'); 
    ELSE 
     RETURN Ip; 
    END IF; 
END UncompressIpV6; 

CREATE FUNCTION Ip2Decimal(IP IN VARCHAR2) RETURN NUMBER DETERMINISTIC IS 
    DecimalIp NUMBER := 0; 
BEGIN 

    IF REGEXP_LIKE(IP, ':') THEN 
     SELECT SUM(Base2Dec(REGEXP_SUBSTR(UncompressIpV6(IP), '[[:xdigit:]]+', 1, LEVEL), BASE_HEX) * POWER(65536, 8-LEVEL)) 
     INTO DecimalIp 
     FROM dual 
     CONNECT BY LEVEL <= 8; 
     RETURN DecimalIp;  
    ELSE 
     SELECT SUM(REGEXP_SUBSTR(IP, '\d+', 1, LEVEL) * POWER(256, 4-LEVEL)) 
     INTO DecimalIp 
     FROM dual 
     CONNECT BY LEVEL <= 4; 
     RETURN DecimalIp; 
    END IF; 

END Ip2Decimal; 

Fonctionne à la fois pour IPv4 et IPv6. Il devrait être assez évident de le faire uniquement pour IPv4, resp. IPv6 fonctionne.

Vous pouvez l'utiliser dans votre clause ORDER BY:

ORDER BY FLAG_V6 NULLS FIRST, Ip2Decimal(IPCIDR) 
+0

merci .C'est OK et je voudrais appliquer cette fonction d'appel de commande en PHP –