Created
March 3, 2013 21:02
-
-
Save georgepsarakis/5078273 to your computer and use it in GitHub Desktop.
Split (explode) function for MySQL. Simple version requires 3 arguments, S (the delimited string), DELIM (delimiter) and S_INDEX the index of the instance of substring between delimiters. The LTSPLIT, RTSPLIT & TSPLIT wrappers perform trimming on the returned substring, on leading, trailing & both characters respectively.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
DROP FUNCTION IF EXISTS SPLIT; | |
DROP FUNCTION IF EXISTS _SPLIT; | |
DROP FUNCTION IF EXISTS RTSPLIT; | |
DROP FUNCTION IF EXISTS LTSPLIT; | |
DELIMITER // | |
-- Simple Split (no trim) | |
CREATE FUNCTION SPLIT(S CHAR(255), DELIM VARCHAR(30), S_INDEX TINYINT UNSIGNED) RETURNS VARCHAR(255) | |
BEGIN | |
RETURN _SPLIT(S, DELIM, S_INDEX, '', 0); | |
END// | |
-- Left-Trim Split | |
CREATE FUNCTION LTSPLIT(S CHAR(255), DELIM VARCHAR(30), S_INDEX TINYINT UNSIGNED, TRIM_CHARS VARCHAR(10)) RETURNS VARCHAR(255) | |
BEGIN | |
RETURN _SPLIT(S, DELIM, S_INDEX, TRIM_CHARS, 1); | |
END// | |
-- Right-Trim Split | |
CREATE FUNCTION RTSPLIT(S CHAR(255), DELIM VARCHAR(30), S_INDEX TINYINT UNSIGNED, TRIM_CHARS VARCHAR(10)) RETURNS VARCHAR(255) | |
BEGIN | |
RETURN _SPLIT(S, DELIM, S_INDEX, TRIM_CHARS, 2); | |
END// | |
-- Both-Trim Split | |
CREATE FUNCTION TSPLIT(S CHAR(255), DELIM VARCHAR(30), S_INDEX TINYINT UNSIGNED, TRIM_CHARS VARCHAR(10)) RETURNS VARCHAR(255) | |
BEGIN | |
RETURN _SPLIT(S, DELIM, S_INDEX, TRIM_CHARS, 0); | |
END// | |
CREATE FUNCTION _SPLIT(S CHAR(255), DELIM VARCHAR(30), S_INDEX TINYINT UNSIGNED, TRIM_CHARS VARCHAR(10), TRIM_TYPE TINYINT UNSIGNED) | |
RETURNS VARCHAR(255) | |
BEGIN | |
DECLARE L_INDEX TINYINT UNSIGNED DEFAULT 0; | |
DECLARE L_INDEX_2 TINYINT UNSIGNED DEFAULT 0; | |
DECLARE L_COUNTER TINYINT UNSIGNED DEFAULT 0; | |
DECLARE S_RETURN VARCHAR(255) DEFAULT ''; | |
IF S_INDEX <= 0 THEN | |
RETURN ''; | |
END IF; | |
SET @L_INDEX = LOCATE(DELIM, S); | |
SET @L_INDEX_2 = 0; | |
SET @L_COUNTER = 1; | |
IF ( @L_INDEX > 0 ) THEN | |
WHILE ( S_INDEX > 1 ) AND ( @L_COUNTER < S_INDEX ) DO | |
IF @L_INDEX > 0 THEN | |
SET @L_INDEX_2 = @L_INDEX; | |
END IF; | |
SET @L_INDEX = LOCATE(DELIM, S, @L_INDEX + 1); | |
SET @L_COUNTER = @L_COUNTER + 1; | |
END WHILE; | |
SET @DELIMITER_ADJUST = -1; | |
IF @L_INDEX = 0 THEN | |
SET @L_INDEX = LENGTH(s); | |
SET @DELIMITER_ADJUST = 0; | |
END IF; | |
SET @S_RETURN = SUBSTRING(S, @L_INDEX_2 + 1, @L_INDEX - @L_INDEX_2 + @DELIMITER_ADJUST); | |
IF TRIM_CHARS != '' THEN | |
CASE TRIM_TYPE | |
WHEN 1 THEN | |
SET @S_RETURN = TRIM(LEADING TRIM_CHARS FROM @S_RETURN); | |
WHEN 2 THEN | |
SET @S_RETURN = TRIM(TRAILING TRIM_CHARS FROM @S_RETURN); | |
ELSE | |
SET @S_RETURN = TRIM(BOTH TRIM_CHARS FROM @S_RETURN); | |
END CASE; | |
END IF; | |
RETURN @S_RETURN; | |
ELSE | |
RETURN 0; | |
END IF; | |
END // | |
DELIMITER ; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Using the SUBSTRING_INDEX this would definitely be easier, omitting the WHILE loop, but where would be the fun in that?
Seriously, it is mainly for educational purposes (for myself first of all), exploring stored functions capabilities and language specifics.