在 sql 服务器中检查字段是否包含多个字符串

Checking if field contains multiple string in sql server

我正在开发一个 sql 数据库,它将提供一些网格数据。网格将启用过滤、排序和分页,但也有严格的要求,例如用户可以在网格上方的文本输入中输入自由文本 'Engine 1001 Requi' 并且结果将仅包含在某些列中包含所有文本片段的行。因此,一列可能包含 Engine,另一列可能包含 1001,而其他一些列可能包含 Requi。

我在 table(我们称它为 myTable)中创建了一个技术专栏(我们称它为 myTechnicalColumn),每次有人插入或更新一行时都会更新它,它将包含所有的所有值用 space.

合并和分隔的列

现在要将它与 entity framework 一起使用,我决定使用一个 table 值函数,它接受一个参数 @searchQuery 并且它将像这样处理它:

CREATE FUNCTION myFunctionName(@searchText NVARCHAR(MAX))
RETURNS @Result TABLE
( ... here come columns )
    AS
    BEGIN
        DECLARE @searchToken TokenType
        INSERT INTO @searchToken(token) SELECT value FROM STRING_SPLIT(@searchText,' ')
    
        DECLARE @searchTextLength INT
        SET @searchTextLength = (SELECT COUNT(*) FROM @searchToken)

        INSERT INTO @Result
        SELECT
        ... here come columns
        FROM myTable
        WHERE (SELECT COUNT(*) FROM @searchToken WHERE CHARINDEX(token, myTechnicalColumn) > 0) = @searchTextLength
        RETURN;
    END

这个解决方案当然可以正常工作,但速度有点慢。任何提示如何提高其效率?

由于没有数据可以测试,我不确定以下是否能解决您的问题:

-- Replace the last INSERT portion
INSERT INTO @Result
   SELECT
        ... here come columns
   FROM myTable T
   JOIN @searchToken S ON CHARINDEX(S.token, T.myTechnicalColumn) > 0

您可以使用内联 Table 值函数,这应该快得多。

这将是您当前代码的直接翻译

CREATE FUNCTION myFunctionName(@searchText NVARCHAR(MAX))
RETURNS TABLE
AS RETURN
(
    WITH searchText AS (
        SELECT value token
        FROM STRING_SPLIT(@searchText,' ') s(token)
    )
    SELECT
        ... here come columns
    FROM myTable t
    WHERE (
        SELECT COUNT(*)
        FROM searchText
        WHERE CHARINDEX(s.token, t.myTechnicalColumn) > 0
    ) = (SELECT COUNT(*) FROM searchText)
);

GO

您正在使用一种名为 无余数关系除法 的查询形式,还有其他方法可以解决这个问题:

CREATE FUNCTION myFunctionName(@searchText NVARCHAR(MAX))
RETURNS TABLE
AS RETURN
(
    WITH searchText AS (
        SELECT value token
        FROM STRING_SPLIT(@searchText,' ') s(token)
    )
    SELECT
        ... here come columns
    FROM myTable t
    WHERE NOT EXISTS (
        SELECT 1
        FROM searchText
        WHERE CHARINDEX(s.token, t.myTechnicalColumn) = 0
    )
);

GO

这可能会更快或更慢,具体取决于多种因素,您需要进行测试。