SQL 空格分隔的多个关键词模糊查询货品资料-任一匹配和全部匹配 数据库实现方式

想要通过实现空格分隔的多个关键词模糊查询货品资料-任一匹配和全部匹配

创建存储过程,根据传入的字符串,以空格分隔之后分词查询
货品代号、名称、规格、图号、材质等多列信息中,至少匹配了一个关键词的货品

 

几个动作

1、建立分割字符串获取关键词并生成一个数据表的函数

--创建函数,以空格分隔字符串,返回一个表变量,方便与数据表进行查询连接
CREATE FUNCTION GETRECORDS(@STR VARCHAR(2000))
    RETURNS 
    @REC TABLE (RECORD VARCHAR(2000))
AS
--    SELECT *  FROM  DBO.GETRECORDS('200g 哈哈 呵呵  呵呵  316L 2333 ')

BEGIN
    DECLARE @REC1 TABLE (RECORD VARCHAR(2000))
    DECLARE @S VARCHAR(2000)
    DECLARE @R VARCHAR(2000)
    DECLARE @I VARCHAR(2000)
    
    --传进来的参数先进行处理,去掉前后的空格,防止出错
    SET @S=LTRIM(RTRIM(ISNULL(@STR,'')))
    --获取第一个空格在字符串中的位置,有空格,则不为0
    SET @I=CHARINDEX(' ',@S)
    
    --对目标字符串进行分隔,插入到返回表中
    WHILE @I>0
    BEGIN
        --从目标字符串中抓取左边的第一个分词,
        --即:截取从第一个字符开始,到第一个分隔符(空格)所在位置之前一位的字符
        SET @R=LEFT(@S,@I-1)
        --写入到返回表中
        INSERT @REC1 VALUES (@R)
        --目标字符串删掉第一个分词和第一个分隔符(空格),剩余部分继续分割处理
        --即:截取从最后一个字符开始,到最后一个分隔符(空格)所在位置之后一位的字
        SET @S=RIGHT(@S,LEN(@S)-@I)
        --获取剩余字符串中,第一个分隔符(空格)在字符串中的位置,有空格,则不为0
        SET @I=CHARINDEX(' ',@S)
    END
    
    --循环处理完毕,若目标字符串长度不为0,则说明是最后一个分词了,直接写入返回表
    IF LEN(@S)>0
    INSERT @REC1 VALUES (@S)

    --分隔结果去重,并且去掉其中的空格
    INSERT INTO @REC (RECORD)
    SELECT DISTINCT RECORD FROM @REC1 WHERE RECORD<>' '
    
    --返回表变量
    RETURN
END

GO

2、建立视图,多个关键词联合到一起

--创建视图 拼接要查询的列到一起,便于比对,用户需要增加查询的列范围,只需要修改视图即可
CREATE VIEW VNPRDT
AS 
--SELECT * FROM VNPRDT
SELECT 
    ISNULL(P.PRD_NO,'') PRD_NO,
    ISNULL(P.NAME,'') NAME,
    ISNULL(CAST(P.SPC AS VARCHAR(1000)),'') SPC,
    ISNULL(P.UT,'') UT,ISNULL(P.PICNO,'') PICNO,
    ISNULL(P.MATERIALKIND,'') MATERIALKIND, 
    ISNULL(P.PRD_NO,'')+ISNULL(P.NAME,'')+ISNULL(CAST(P.SPC AS VARCHAR(1000)),'')+ISNULL(P.UT,'')+ISNULL(P.PICNO,'')+ISNULL(P.MATERIALKIND,'') SERCHKEY
FROM PRDT P
WHERE 1=1

GO

3、建立存储过程,最终实现查询

CREATE PROC SP_PRDTSEARCH
@KEYWORDS NVARCHAR(2000),
@I INT=1
AS
BEGIN      
    --    EXEC SP_PRDTSEARCH '225 花生  EEE W2 嘎嘎',1
    --    EXEC SP_PRDTSEARCH '225 花生',1
    --    EXEc SP_PRDTSEARCH N'225g', 0

    --创建存储过程,根据传入的字符串,以空格分隔之后分词查询 
    --货品代号、名称、规格、图号、材质等多列信息中,
    --至少匹配了一个关键词的货品

    DECLARE @KEYNUMBER INTEGER
    --根据参数传入方式,@I=0 则任意一个关键词匹配即可(OR模式);若@I<>0,则必须匹配所有关键词才行(AND模式)
    IF @I<>0
        BEGIN
            --采用ND模式,获取关键词个数,所有关键词必须全部匹配
            SELECT @KEYNUMBER=COUNT(*) FROM DBO.GETRECORDS(@KEYWORDS)
        END
    ELSE
        BEGIN
            --采用OR模式,任意一个及一个以上关键词匹配即可    
            SELECT @KEYNUMBER=1
        END

    IF ISNULL(@KEYWORDS,'*')='*'
        BEGIN
            SELECT 
                PRD_NO,
                [NAME],
                SPC,
                PICNO,
                MATERIALKIND,
                1 FINDTIMES  
            FROM 
                VNPRDT 
            WHERE 
                1=1
            
        END
    ELSE 
        BEGIN
            SELECT * FROM 
                (
                    SELECT 
                        PRD_NO,
                        [NAME],
                        SPC,
                        PICNO,
                        MATERIALKIND,
                        COUNT(CHARINDEX(B.RECORD,A.[NAME])) FINDTIMES 
                    FROM 
                        VNPRDT A,DBO.GETRECORDS(@KEYWORDS) B
                    WHERE 
                        CHARINDEX(B.RECORD,A.SERCHKEY)>0
                    GROUP BY 
                        A.PRD_NO,A.[NAME],SPC,PICNO,MATERIALKIND
                ) P1
            WHERE 
                P1.FINDTIMES>=@KEYNUMBER
            ORDER BY 
                P1.FINDTIMES
        END 
END
GO
    

调用时,SP_PRDTSEARCH的参数 @I 用于区分是全部匹配还是任意一个匹配即可。

 

 

SQL SERVER 2000数据库,测试了FAS2000系列、SUNLIKE系列、天心、天思、有利、GXXX KERP等同系源ERP产品P的货品资料表,可用。

 

posted on 2021-11-28 21:47  米卢的教练  阅读(1139)  评论(0编辑  收藏  举报

导航