那位知道也麻烦解答一下,这是 zjcxc(邹建) 上午给的函数,可以解决第一种车次情况。
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[f_CompSTR]') and xtype in (N'FN', N'IF', N'TF'))
drop function [dbo].[f_CompSTR]
GOCREATE FUNCTION f_CompSTR(
@s1 varchar(8000),   --包含车次的字符串
@s2 varchar(100)     --要查询的值
)RETURNS varchar(100)
AS
BEGIN
DECLARE @h varchar(100),@s varchar(100),@l int
SELECT @h=LEFT(@s1,CHARINDEX('/',@s1+'/')-1)
,@l=len(@h)+1
,@s1=STUFF(@s1,1,CHARINDEX('/',@s1+'/'),'')
IF @h=@s2 RETURN(1)
WHILE CHARINDEX('/',@s1)>0
BEGIN
SELECT @s=LEFT(@s1,CHARINDEX('/',@s1)-1)
,@s1=STUFF(@s1,1,CHARINDEX('/',@s1),'')
IF len(@s)<@l
SET @s=STUFF(@h,@l-len(@s),100,@s)
if @s=@s2 RETURN(1)END
IF len(@s1)<@l
SET @s1=STUFF(@h,@l-len(@s1),100,@s1)
return(case when @s2=@s1 then 1 else 0 end)
END
GO--测试
select * from(
select cc='k8' union all 
select cc='t5' union all 
select cc='K60/1/0/1' union all 
select cc='28030/29' union all 
select cc='k61' 
)a where (dbo.f_CompSTR(cc, 'k61') = 1)/*--结果
cc        
--------- 
K60/1/0/1
k61(所影响的行数为 2 行)
--*/

解决方案 »

  1.   

    if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[f_CompSTR]') and xtype in (N'FN', N'IF', N'TF'))
    drop function [dbo].[f_CompSTR]
    GOCREATE FUNCTION f_CompSTR(
    @s1 varchar(8000),   --包含车次的字符串
    @s2 varchar(100)     --要查询的值
    )RETURNS bit
    AS
    BEGIN
    SELECT @s1=REPLACE(@s1,a,b)
    FROM(
    SELECT a='(',b='/' UNION ALL
    SELECT a='.',b='/' UNION ALL
    SELECT a=' ',b='/' UNION ALL
    SELECT a='"',b='' UNION ALL
    SELECT a=')',b='' UNION ALL
    SELECT a='备',b='')a
    DECLARE @h varchar(100),@s varchar(100),@l int
    SELECT @h=LEFT(@s1,CHARINDEX('/',@s1+'/')-1)
    ,@l=len(@h)+1
    ,@s1=STUFF(@s1,1,CHARINDEX('/',@s1+'/'),'')
    IF @h=@s2 RETURN(1)
    WHILE CHARINDEX('/',@s1)>0
    BEGIN
    SELECT @s=LEFT(@s1,CHARINDEX('/',@s1)-1)
    ,@s1=STUFF(@s1,1,CHARINDEX('/',@s1),'')
    IF len(@s)<@l
    SET @s=STUFF(@h,@l-len(@s),100,@s)
    if @s=@s2 RETURN(1)
    END IF len(@s1)<@l
    SET @s1=STUFF(@h,@l-len(@s1),100,@s1)
    return(case when @s2=@s1 then 1 else 0 end)
    END
    GO
    select cc
    from(
    select cc='1434/1/4/1' union all --表示车次1434和车次1431
    select cc='"10653(85707)"' union all --:表示车次10653和车次85707
    select cc='"32608/7(83212/1)"' union all --表示车次32608,32607和车次83212和83211
    select cc='"50057()"' union all --表示车次50057
    select cc='"T888(备)"' union all --表示车次T888
    select cc='"21058(81404/3)0"' union all --表示车次21058,81404和81403(后面的0输入错误,不管)
    select cc='"22028(80404.10264)"' union all --表示车次22028,80404和10264
    select cc='20037(80303.84006/9)' union all --表示车次20037,80303,84006和84009
    select cc='24031(80410/9' union all --表示车次24031,80410和80419
    select cc='24048(80904)(23118)' union all --表示车次24048,80904,23118
    select cc='22080(80406.83080.10284)' union all --表示车次22080,80406,83080,10284
    select cc='0031(5632 5629)'  --表示车次0031,5632,5629(中间是一个空格)
    )a where dbo.f_CompSTR(cc,'85707')=1
      

  2.   

    请教老大下面两点:SELECT @s1=REPLACE(@s1,a,b)
    FROM(
    SELECT a='(',b='/' UNION ALL
    SELECT a='.',b='/' UNION ALL
    SELECT a=' ',b='/' UNION ALL
    SELECT a='"',b='' UNION ALL
    SELECT a=')',b='' UNION ALL
    SELECT a='备',b='')a有什么作用?IF len(@s)<@l
      SET @s=STUFF(@h,@l-len(@s),100,@s)
    是什么意思?
      

  3.   

    作用就是把你的不规范的cc变成统一的以/分隔的车次
    IF len(@s)<@l
      SET @s=STUFF(@h,@l-len(@s),100,@s)
    作用就是把编码不全的,按照第一个编码补全
      

  4.   

    老大如果用
    SELECT @s1=REPLACE(@s1,a,b)
    FROM(
    SELECT a='(',b='/' UNION ALL
    SELECT a='.',b='/' UNION ALL
    SELECT a=' ',b='/' UNION ALL
    SELECT a='"',b='' UNION ALL
    SELECT a=')',b='' UNION ALL
    SELECT a='备',b='')a
    替换的话,还是有问题的:
    32608/7(83212/1)->32608/32607/83212/1:意味着原来的车次83211查不出,出现原来没有的车次32601
    21058(81404/3)0->21058/81404/30:意味着81403查不出,出现新编号21030
    20037(80303.84006/9)同上
    24031(80410/9同上
    另外‘备’只是我举的一个特例。如果括号里面是汉字就应该忽略,而不是含只有‘备’字不过老大能这么快搞定这个函数,我只能用机器人来形容你了!
      

  5.   

    IF len(@s)<@l
      SET @s=STUFF(@h,@l-len(@s),100,@s)
    作用就是把编码不全的,按照第一个编码补全
    能不能详细点?
      

  6.   

    如果还要处理得这么细的话,那就只能逐字拆分了,遇到(就变换而对于
    21058(81404/3)0->21058/81404/30:意味着81403查不出,出现新编号21030那如果是
    21058(81404/3)1  是否也忽略1呢?
    如果是
    21058(81404/3)10  是否也忽略10呢?
    如果是
    21058(81404/3)00  是否也忽略00呢?如果是
    "T888(ab)" 是否忽略ab呢?这样的变数太多种,你要处理得好,必须在函数中把这些情况全部列出来
      

  7.   

    咳,要是我能自己修改数据就好了。可惜不行。
    对车次k14/1/4/1这种类型和车次k15/7(1234/5)这种类型的车次。其实是行业已经形成的习惯
    没有办法改的。
    只有如:
    "50057()"
    "T888(备)"
    "21058(81404/3)0
    20037(80303.84006/9)
    24031(80410/9
    22080(80406.83080.10284)
    0031(5632 5629)
    这些才是非标准的输入。
      

  8.   

    顺带问一下:
    --测试
    select * from(
    select cc='k8' union all 
    select cc='t5' union all 
    select cc='K60/1/0/1' union all 
    select cc='28030/29' union all 
    select cc='k61' 
    )a where (dbo.f_CompSTR(cc, 'k61') = 1)中的
    select cc='k8' union all 
    select cc='t5' union all 
    select cc='K60/1/0/1' union all 
    select cc='28030/29' union all 
    select cc='k61' 
    是什么意思
      

  9.   

    老大就是牛,我终于搞定了。
    CREATE FUNCTION f_CompSTR(
    @s1 varchar(8000),   --包含车次的字符串
    @s2 varchar(100)     --要查询的值
    )RETURNS bit
    AS
    BEGIN
      IF @s1=@s2 return(1)
      IF CHARINDEX('(',@s1)<=0 and CHARINDEX('/',@s1)<=0 and CHARINDEX('.',@s1)<=0 and CHARINDEX(' ',@s1)<=0 and
      CHARINDEX('(',@s1)<=0 and  CHARINDEX(')',@s1)<=0 and CHARINDEX(')',@s1)<=0 return (0) 
      SELECT @s1=REPLACE(@s1,a,b)
       FROM(
    SELECT a='.',b='(' UNION ALL
    SELECT a=' ',b='(' UNION ALL
    SELECT a='(',b='(' UNION ALL
    SELECT a=')',b='(' UNION ALL
    SELECT a=')',b='(' )a  DECLARE @h varchar(100),@a varchar(100),@b varchar(100),@s varchar(100),@l int
      table_loop:
      IF CHARINDEX('(',@s1)>0--对含括号的字符串进行分解处理,a为前部分,b为后部分
      BEGIN
        SELECT @a=LEFT(@s1,CHARINDEX('(',@s1)-1),
        @b=STUFF(@s1,1,CHARINDEX('(',@s1),'')
        set @s1=@a
      END
      SELECT @h=LEFT(@s1,CHARINDEX('/',@s1+'/')-1)
      ,@l=len(@h)+1
      ,@s1=STUFF(@s1,1,CHARINDEX('/',@s1+'/'),'')
      IF @h=@s2 RETURN(1)
      WHILE CHARINDEX('/',@s1)>0
      BEGIN
        SELECT @s=LEFT(@s1,CHARINDEX('/',@s1)-1)
        ,@s1=STUFF(@s1,1,CHARINDEX('/',@s1),'')
        IF len(@s)<@l
          SET @s=STUFF(@h,@l-len(@s),100,@s)
        if @s=@s2 RETURN(1)
      END
      IF len(@s1)<@l
        SET @s1=STUFF(@h,@l-len(@s1),100,@s1)
      IF @s1=@s2 return(1)
      IF len(@b)>0
      BEGIN
        SET @s1=@b
        SET @b=''
        GOTO table_loop
      END
      return(case when @s2=@s1 then 1 else 0 end)
    END
    GO