这是我第一次尝试SQL函数。我在VB中写了它,它就像一个魅力。当我将它翻译为SQL Server时,它不会返回我所期望的。该函数的目的是返回两个字符串的百分比匹配。
我期望它如何运作是这样的:
我期望的一个例子是我将“CAT”与“CART”进行比较。我的预期回报是7/12 ...... 0.58。相反,我得到0.如果我将“CAT”与“CAT”进行比较,我期望9/9 ... 1.00。相反,我得到了2.
(2014年9月17日的注意事项:感谢您的意见。我使用了您的建议,并做了一个重大改变,这不会影响我的要求,除了得到正确的最终答案是我摆脱了第二个While循环。相反,我在@ strWord2中搜索@strLetter。如果找到它,那么,我看看它是否与@ strWord1在@ strWord2中的位置相同。如果是,那么我添加3,如果没有,我添加1.这加快了功能并使计数准确。
以下是代码:
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;
答案 0 :(得分:1)
我做的最重要的改变是
在括号外乘以乘以除法得分的整数结果乘以长度。如果此答案已经为零,则乘法结果也为零。
我做的其他更改在代码中被注释:变量intWordLoop2对计算没有影响,可以删除; strLetter可以声明为Char(1)而不是VarChar(1000)。
CREATE FUNCTION [dbo].[CompareWords]
(@strWord1 VARCHAR(2000), @strWord2 VARCHAR(2000))
RETURNS DECIMAL
AS
BEGIN
SET @strWord1 = UPPER(@strWord1)
SET @strWord2 = UPPER(@strWord2)
--Set @intLength (maxLength as len of word1 or word2)
DECLARE @intLength INT --maxLength
IF LEN(@strWord1) >= LEN(@strWord2)
BEGIN
SET @intLength = LEN(@strWord1)
END
ELSE
BEGIN
SET @intLength = LEN(@strWord2)
END
DECLARE @iWordLoop1 INT, @iWordLoop2 INT--, @intWordLoop2 INT --This variable doesn't impact the calculation
DECLARE @intWordScore INT
DECLARE @intLetterScore INT
SET @intWordScore = 0
--SET @intWordLoop2 = Len(@strWord2)--this value is not used anywhere else, so removing makes no difference.
--DECLARE @strLetter VARCHAR(1000)
DECLARE @strLetter CHAR(1)--there is no need for 1000 characters since we're only ever assigning a single character to this
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 @intLetterScore = 0
SET @count2 = (@count2 + 1)
END
SET @count1 = (@count1 + 1)
END
DECLARE @sinScore DEC
SET @sinScore = (@intWordScore*100 / (3 * @intLength))
RETURN @sinSCore
END;
select dbo.comparewords ('Cat','cart')