This was my first attempt at a SQL function. I wrote it in VB and it works like a charm. When I translated it to SQL Server, it returns not what I expect. What the function is intended to do is to return a percentage match of two strings.
How I expected it to function is this:
- accept two strings, compare the two, and based on my rating values, return a percentage of the match value...matchscore/max possiblescore
- The length of the larger string is multiplied by 3. This is the max possiblescore.
- Go character by character of the first string and find that character in the second string.
- If the character is found in the same position in the second string, add three to the matchscore and move on to the next letter.
- If the character is found in the second word, but not in the same position, add one to match score and move on to the next character.
- If the character is not found in the second string, add nothing and move on to the next character.
- Divide the matchscore by the max possiblescore. This returns a decimal value. I read RETURN only returns an integer, so I multiplied the division result by 100.
An example of what I expected is I compare "CAT" to "CART". My expected return is 7/12...0.58. Instead, I get 0. If I compare "CAT" to "CAT", I expect 9/9...1.00. Instead, I get 2.
(Note from 9/17/2014: I appreciate your input. I used what you suggested, and did one more major change, that doesn't affect what I asked about, other than getting the correct final answer is that I got rid of the second While Loop. Instead, I search for @strLetter in @strWord2. If it is found, then, I look to see if it is in the same position in @strWord2 as @strWord1. If it is, then I add 3, if not, I add 1. This sped up the function and made the count accurate.
Here is the code:
CREATE FUNCTION [dbo].[CompareWords]
(@strWord1 VARCHAR(2000), @strWord2 VARCHAR(2000))
RETURNS DECIMAL
AS
BEGIN
SET @strWord1 = UPPER(@strWord1)
SET @strWord2 = UPPER(@strWord2)
DECLARE @intLength INT
IF LEN(@strWord1) >= LEN(@strWord2)
BEGIN
SET @intLength = LEN(@strWord1)
END
ELSE
BEGIN
SET @intLength = LEN(@strWord2)
END
DECLARE @iWordLoop1 INT
DECLARE @iWordLoop2 INT
DECLARE @intWordLoop2 INT
DECLARE @intWordScore INT
DECLARE @intLetterScore INT
SET @intWordScore = 0
SET @intWordLoop2 = Len(@strWord2)
DECLARE @strLetter VARCHAR(1000)
DECLARE @count1 INT
SET @count1 = 0
SET @iWordLoop1 = Len(@strWord1)
WHILE (@count1 < @iWordLoop1)
BEGIN
SET @strLetter = SUBSTRING(@strWord1, @count1+1, 1)
SET @intLetterScore = 0
DECLARE @count2 INT
SET @count2 = 0
SET @iWordLoop2 = Len(@strWord2)
WHILE (@count2 < @iWordLoop2)
BEGIN
If @strLetter = SUBSTRING(@strWord2, @count2+1, 1)
BEGIN
If @iWordLoop1 = @iWordLoop2
BEGIN
SET @intLetterScore = 3
SET @iWordLoop2 = Len(@strWord2)
END
ELSE
BEGIN
SET @intLetterScore = 1
END
END
SET @intWordScore = @intWordScore + @intLetterScore
SET @count2 = (@count2 + 1)
END
SET @count1 = (@count1 + 1)
END
DECLARE @sinScore DEC
SET @sinScore = (@intWordScore / (3 * @intLength)) * 100
RETURN @sinSCore
END;
7/12evaluates to0. Not sure about your other issue without running it.