1

我尝试搜索Dhaka is the capital of Bangladesh包含六个单词的字符串。如果我的搜索文本是cap(这是大写的起始文本),它将为我提供字符串中搜索文本的起始索引(此处为 14)。如果搜索文本包含在字符串中但不包含任何单词的起始文本,它将给我 0。请查看测试用例以更好地理解。

我试过的

DECLARE @SearchText VARCHAR(20),
        @Str VARCHAR(MAX),
        @Result INT

SET @Str = 'Dhaka is the capital of Bangladesh'
SET @SearchText = 'cap'

SET @Result = CASE WHEN @Str LIKE @SearchText + '%'
                      OR @Str LIKE + '% ' + @SearchText + '%' 
                   THEN CHARINDEX(@SearchText, @Str)
              ELSE 0 END

PRINT @Result -- print 14 here

就我而言,我需要@Str使用另一个 sql 函数生成。在这里,我们需要生成@Str3 次,这很昂贵(我认为)。那么,有什么方法可以让我@Str只需要生成一次吗?[是否可以通过使用PATINDEX]

注意: CASE条件出现在我原始查询的 where 子句中。因此,不可能@Str在变量中设置值然后在 where 子句中使用它。

测试用例

  1. Search Text:达卡, Result: 1
  2. Search Text:, Result: 0
  3. Search Text:米尔普尔, Result: 0
  4. Search Text:, Result: 0
  5. Search Text:, Result: 7
  6. Search Text:达卡首都, Result: 0
4

2 回答 2

1

要在 SELECT 中每行仅计算一次函数,请使其成为表值函数。或者如果由于某种原因不可能使用 CROSS APPLY

SELECT .. a, b,
FROM ..
CROSS APPLY (SELECT my_scalar_fn(a,b) as Str) arg
WHERE CASE WHEN arg.Str LIKE SearchText + '%'
                      OR arg.Str LIKE + '% ' + SearchText + '%' 
                   THEN CHARINDEX(SearchText, arg.Str)
              ELSE 0 END
于 2016-06-08T10:03:42.243 回答
1

只需在字符串中添加一个前导空格,以确保您始终只找到单词的开头:

DECLARE @SearchText VARCHAR(20),
        @Str VARCHAR(MAX),
        @Result INT

SET @Str = 'Dhaka is the capital of Bangladesh'
SET @SearchText = 'Dhaka Capital'
SET @Result = CHARINDEX(' ' + @SearchText, ' ' + @Str)

PRINT @Result -- print 14 here

我已经针对您的测试用例测试了上述查询,它似乎有效。

于 2016-06-08T10:10:08.963 回答