那位知道也麻烦解答一下,这是 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 行)
--*/
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 行)
--*/
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
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)
是什么意思?
IF len(@s)<@l
SET @s=STUFF(@h,@l-len(@s),100,@s)
作用就是把编码不全的,按照第一个编码补全
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同上
另外‘备’只是我举的一个特例。如果括号里面是汉字就应该忽略,而不是含只有‘备’字不过老大能这么快搞定这个函数,我只能用机器人来形容你了!
SET @s=STUFF(@h,@l-len(@s),100,@s)
作用就是把编码不全的,按照第一个编码补全
能不能详细点?
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呢?这样的变数太多种,你要处理得好,必须在函数中把这些情况全部列出来
对车次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)
这些才是非标准的输入。
--测试
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'
是什么意思
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