2012-11-12 37 views
2

我有一張表,其中包含域名和說明列表。SQL(更喜歡MySQL)字符串反向域名的功能

我希望使用一個簡單的函數(本地函數,如果可能的話)顛倒域名錶示法,以更好,更自然的排序順序(個人意見)使用。

例如,我想有轉換下列數據從左至右:

admin.test.example.com => com.example.test.admin 
api.test.example.com => com.example.test.api 
cdn.test.example.com => com.example.test.cdn 
test.example.com => com.example.test 
admin.staging.example.com => com.example.staging.admin 
api.staging.example.com => com.example.staging.api 
cdn.staging.example.com => com.example.staging.cdn 
staging.example.com => com.example.staging 

在PHP中做到這一點我可以做喜歡的事很簡單:

$rev_domain = implode('.', array_reverse(explode('.', $domain))); 

這是容易實現在SQL中? (更喜歡SQL標準合規性,或者MySQL如果需要擴展,或者兩者兼而有之)。

很明顯,另一種選擇是創建並維護一個包含反向DNS名稱的新列,但是我正在尋找可以在查詢中即時使用的內容。

在此先感謝!

編輯:我在尋找一個解決方案,可爲子域部分的任何數,例如工作:example.com和1.2.3.4.5.6.7.8.9.0.example.com

+0

你將不得不編寫自己的函數,遍歷輸入字符串搜索'.'字符。 – eggyal

+0

您是否真的需要保留標籤內的遠期訂單?對於大多數目的來說'REVERSE'應該足以滿足您的需求。 – kmkaplan

+1

簡單地顛倒字符串不會創造我所希望的自然排序能力。例如,它不會將「admin」和「api」緊密放在一起,因爲最終域名部分的第一個字符是api(i)+ admi(n),而不是(a)pi +(a)dmin。 –

回答

1

試試這個:

CREATE FUNCTION reverse_dns (s CHAR(255)) 
RETURNS CHAR(255) DETERMINISTIC 
BEGIN 
    DECLARE i, j INT; 
    DECLARE r CHAR(255); 
    SET j = LOCATE('.', s, 1); 
    IF j = 0 THEN 
     RETURN s; 
    END IF; 
    SET r = LEFT(s, j - 1); 
    SET i = j + 1; 
    LOOP 
     SET j = LOCATE('.', s, i); 
     IF j = 0 THEN 
      SET r = CONCAT(RIGHT(s, LENGTH(s) - i + 1), '.', r); 
      RETURN r; 
     END IF; 
     SET r = CONCAT(SUBSTRING(s, i, j - i), '.', r); 
     SET i = j + 1; 
    END LOOP; 
END; 
+0

謝謝 - 這個效果很好!希望有一個簡單的問題 - 如何修改長達4KB到8KB的字符串?雖然不常見,但域名很容易超過255個字節。 –

+0

實際上,域名被限制爲255個字節。請參閱RFC 1034 3.1。名稱空間規範和術語:「代表域名的八位字節總數限制爲255.」 – kmkaplan

+0

對不起,我站在更正 - 謝謝! –

0

這是不是特別漂亮,但你可以做這樣的事情:

select concat(left(substring_index(concat(val, '.'), '.', -2), 
        locate('.', substring_index(concat(val, '.'), '.', -2)) 
       ), 
       left(substring_index(concat(val, '.'), '.', -3), 
        locate('.', substring_index(concat(val, '.'), '.', -3)) 
       ), 
       left(substring_index(concat(val, '.'), '.', -4), 
        locate('.', substring_index(concat(val, '.'), '.', -4)) 
       ), 
       left(substring_index(concat(val, '.'), '.', -5), 
        locate('.', substring_index(concat(val, '.'), '.', -5))-1 
       ) 
      ) 

一個MySQL的優勢之一是,它具有良好的字符串函數,以及SUBSTRING_INDEX就是其中之一。

+0

謝謝,不幸的是,我不能看到這個工作與域內的可變數量的子部分 - 糾正我,如果我錯了,但這專門處理了一個4部分的情況?我會更新上面的問題以幫助更具體。 –

+0

要處理可變數量的零件,需要更復雜的邏輯。 –