俺の報告

RoomClipを運営するエンジニアの日報(多分)です。

MySQLでバージョン形式を認識する関数 - 日報 #124

花粉がどえらいことになっとるようです。
僕のCloudWatchはずーっとAlert出しっぱなしです。
対策は修正コードをpatchすればいいのですが、
このpatchは有効期限があって定期的な運用が必要になります。

だるいわぁ。。。

なんか大量の花粉対策薬を事前に腹にいれといて、
定期的に少量ずつ注入して欲しいです。
cronのように。

さて、本日はちょっとしたSQLのクエリチップスを。
バージョン表記ってあるじゃないですか。
例えば、ver 5.3.1 みたいな。
これをDBに突っ込んだ時、結構扱いづらくなったりします。
メジャーバージョン4以上の、、、とかそういう条件が組めなくなるんですね。
まぁ別にやり方は他にいも色々あるので、別にクエリで解決しなくても問題ないんですが、
クエリだってデキる子なはずなので、バージョンを桁ごとに抽出する関数を自作しました。
まぁほとんど使わないと思いますが、、、
MySQLだって色々とFunctionでできるんだってことが分かりました。

使い方としては、
get_version("5.3.1", 2)
のように書くと 5.3.1 の二桁目なので 3 が返る、という関数です。
SPLIT関数があればよかったのですが、そんなものないので、POSTIONを追跡する形で、
なんとかしております。
version_table テーブルに、versionカラムというのがあって、
そこに任意の桁数 5.3.1 のような文字列が入ってるとします。
その時、こんなクエリを書くと、一発で目的の桁を抽出することができます。

DROP FUNCTION IF EXISTS get_version ;

DELIMITER //
CREATE FUNCTION get_version(
  `str` TEXT,
  `section` INT
)
RETURNS VARCHAR(10) DETERMINISTIC

BEGIN
 
  DECLARE result VARCHAR(10);
  DECLARE counter INT(10);
  DECLARE start_pos INT(10);
  DECLARE end_pos INT(10);
  DECLARE tmp_pos INT(10);
 
  SET start_pos=1;
  SET end_pos=LOCATE('.', str, start_pos);
  SET counter=1;
  WHILE counter < section DO
    SET tmp_pos=end_pos+1;
    SET end_pos=LOCATE('.', str, end_pos+1);
    IF end_pos = 0 THEN
      SET end_pos=LENGTH(str)+1;
    END IF;
    SET start_pos=tmp_pos;
    SET counter=counter + 1;
  END WHILE;
 
  SET result=SUBSTRING(str, start_pos, end_pos-start_pos);

  RETURN result;

END;
//
DELIMITER ;

SELECT
  version,
  get_version(appversion, 1) AS major,
  get_version(appversion, 2) AS minor,
  get_version(appversion, 3) AS fix
FROM version_table;

-- | 5.3.1 | 5 | 3 | 1 | と出力されます。

便利、、、なこともないと思いますが、
なんかに使えればどうぞ。