想要通过实现空格分隔的多个关键词模糊查询货品资料-任一匹配和全部匹配
创建存储过程,根据传入的字符串,以空格分隔之后分词查询
货品代号、名称、规格、图号、材质等多列信息中,至少匹配了一个关键词的货品
几个动作
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的货品资料表,可用。