Question

I tried recreating an SQL server function on MySQL. The function should be able to return a string with spaces before capital letters. For example, writing "HelloWorld" would return "Hello World".

Other Examples:

"IanLikesJane" -> "Ian Likes Jane"

"CodLiverOil" -> "Cod Liver Oil"

My logic is as follows

result string = ''
Foreach character in input string:

  If this letter is capital:
    If the preceding or next letter is not capital:
      If the the preceding and current letter is not a space:
        Concatinate space after result string

Concatinate this letter with result

MySQL:

DELIMITER $$
CREATE FUNCTION SpaceBeforeCapital (str NVARCHAR(8000)) 
RETURNS NVARCHAR(8000)
DETERMINISTIC
BEGIN
DECLARE i INT; 
DECLARE j INT;
DECLARE cp NCHAR;
DECLARE c0 NCHAR;
DECLARE c1 NCHAR;
DECLARE result NVARCHAR(8000);

SET i = 1;
SET j =  CHAR_LENGTH(str);
SET result = '';    

WHILE (i <= j) DO       
   SET cp = SUBSTRING(str,(i-1),1);
   SET c0 = SUBSTRING(str,i,1);
   SET c1 = SUBSTRING(str,(i+1),1);

   -- IF c0 = UPPER(c0) THEN
   -- IF c0 = UPPER(CONVERT(c0 USING latin1)) AND (cp != UPPER(CONVERT(cp USING latin1)) OR c1 != UPPER(CONVERT(c1 USING latin1))) 
    IF c0 = UPPER(CONVERT(c0 USING latin1)) THEN
        IF cp != UPPER(CONVERT(cp USING latin1)) OR c1 != UPPER(CONVERT(c1 USING latin1)) THEN
            IF cp != ' ' AND c0 != ' ' THEN
                SET result = CONCAT(result,' ');
            END IF;
        END IF;
    END IF;
   -- END IF; 

   SET result = CONCAT(result,c0);
   SET i = i + 1;

END WHILE;

RETURN result;
END$$
DELIMITER;

My script is pretty much doing the opposite the input strings without any spaces. Anyone got a fix?

Was it helpful?

Solution

I reckon that the problem here is that case sensitivity is not working as you'd like.

Try replacing UPPER with BINARY UPPER to force case sensitivity. Hence:

DELIMITER $$


CREATE FUNCTION SpaceBeforeCapital (str NVARCHAR(8000)) 
RETURNS NVARCHAR(8000)
DETERMINISTIC
BEGIN
DECLARE i INT; 
DECLARE j INT;
DECLARE cp NCHAR;
DECLARE c0 NCHAR;
DECLARE c1 NCHAR;
DECLARE result NVARCHAR(8000);

SET i = 1;
SET j =  CHAR_LENGTH(str);
SET result = '';    

WHILE (i <= j) DO       
   SET cp = SUBSTRING(str,(i-1),1);
   SET c0 = SUBSTRING(str,i,1);
   SET c1 = SUBSTRING(str,(i+1),1);

   -- IF c0 = UPPER(c0) THEN
   -- IF c0 = UPPER(CONVERT(c0 USING latin1)) AND (cp != UPPER(CONVERT(cp USING latin1)) OR c1 != UPPER(CONVERT(c1 USING latin1))) 
    IF c0 = BINARY UPPER(CONVERT(c0 USING latin1)) THEN
        IF cp != BINARY UPPER(CONVERT(cp USING latin1)) OR c1 != BINARY UPPER(CONVERT(c1 USING latin1)) THEN
            IF cp != ' ' AND c0 != ' ' THEN
                SET result = CONCAT(result,' ');
            END IF;
        END IF;
    END IF;
   -- END IF; 

   SET result = CONCAT(result,c0);
   SET i = i + 1;

END WHILE;

RETURN result;
END$$


DELIMITER ;

OTHER TIPS

If still no luck from others, I have the following two suggestions... Try just using UPPER() without convert / Latin1... as you already have a single character to deal with.

IF c0 = UPPER(c0) THEN

same with rest of upper() conversion tests

If that does not work, I would then build a string at the beginning of your function such as

DECLARE AllUpper NVARCHAR(26);
SET AllUpper = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';

then use INSTR() to see if the character is in the all upper string

   IF INSTR( AllUpper, c0 ) > 0

similar with upper conversion tests

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top