如何在sql server中检查和更改自定义字符串

如何在sql server中检查和更改自定义字符串,sql,sql-server,Sql,Sql Server,我的sql查询代码有问题 我有一列代码和这样的代码结构 3digit-1to3digit-5to7digit-1to2digit xxx-xxx-xxxxxx-xx 在“代码”列中,用户添加如下代码 1-1486414-305-115 --mistake 116-500-325663-1 --ok 116-2-2244880-1 --ok 121-512-2623075-1 --ok 122-500-1944261-3 --ok 2-2651274-500-147 --mistake

我的sql查询代码有问题 我有一列代码和这样的代码结构

3digit-1to3digit-5to7digit-1to2digit
xxx-xxx-xxxxxx-xx
在“代码”列中,用户添加如下代码

1-1486414-305-115 --mistake
116-500-325663-1  --ok
116-2-2244880-1   --ok
121-512-2623075-1 --ok
122-500-1944261-3 --ok
2-2651274-500-147 --mistake 
1-2551671-305-147 --mistake 
124-500-329130-1  --ok
如何检查和修复错误代码


感谢您阅读我的问题

真是太痛苦了,因为SQL Server不支持正则表达式

一种方法是6类比较:

where col like '[0-9][0-9][0-9]-[0-9][0-9][0-9]-[0-9][0-9][0-9][0-9][0-9]-[0-9]' or
      col like '[0-9][0-9][0-9]-[0-9][0-9][0-9]-[0-9][0-9][0-9][0-9][0-9]-[0-9][0-9]' or
      col like '[0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]-[0-9][0-9][0-9][0-9][0-9]-[0-9]' or
      col like '[0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]-[0-9][0-9][0-9][0-9][0-9]-[0-9][0-9]' or
      col like '[0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]-[0-9][0-9][0-9][0-9][0-9]-[0-9]' or
      col like '[0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]-[0-9][0-9][0-9][0-9][0-9]-[0-9][0-9]' or
      col like '[0-9][0-9][0-9]-[0-9][0-9][0-9][0-9][0-9]-[0-9][0-9][0-9][0-9][0-9]-[0-9]' or
      col like '[0-9][0-9][0-9]-[0-9][0-9][0-9][0-9][0-9]-[0-9][0-9][0-9][0-9][0-9]-[0-9][0-9]'
否则,您可以计算-s,检查位置和字符。因此:

where col not like '[^-0-9]' and  -- only has digits and -
      col not like '%-%-%-%-%' and -- does not have 4 hyphens
      col like '___-___-%-%[0-9]' and -- first two hyphens in the right place and ends in digit
      '-' in (substring(col, 14, 1), substring(col, 15, 1), substring(col, 16, 1)) -- last hyphen in the right place

或者,您可以拆分部分并检查它们的长度,然后检查字符串是否只包含带有LIKE的数字和连字符,而不是加载一堆类似的表达式。由于字符串有4个部分,所以我在这里使用了PARSENAME,而不是splitter函数

SELECT *
FROM (VALUES ('1-1486414-305-115'),
             ('116-500-325663-1'), 
             ('116-2-2244880-1'),
             ('121-512-2623075-1'), 
             ('122-500-1944261-3'), 
             ('2-2651274-500-147'), 
             ('1-2551671-305-147'), 
             ('116-ba-2244880-1'),
             ('124-500-329130-1'))V(Code)
     CROSS APPLY (VALUES(PARSENAME(REPLACE(V.code,'-','.'),4),
                         PARSENAME(REPLACE(V.code,'-','.'),3),
                         PARSENAME(REPLACE(V.code,'-','.'),2),
                         PARSENAME(REPLACE(V.code,'-','.'),1))) PN(P1, P2, P3, P4) 
WHERE LEN(P1) != 3
   OR NOT(LEN(P2) BETWEEN 1 AND 3)
   OR NOT(LEN(P3) BETWEEN 5 AND 7)
   OR NOT(LEN(P4) BETWEEN 1 AND 2)
   OR V.Code LIKE '%[^0-9\-]%' ESCAPE '\';

下面是可以实现所需结果的完整代码

1将拆分后的字符串存储到表@myvalues中我已经编写了一个解决方案,使用Recursivity将字符串拆分为多行

2将条件存储在表格@tabcheck每个字符串的长度中

3在@myvalues和@tabcheck之间进行连接以获得结果

declare @str as nvarchar(max)
set @str='116-500-325663-1';
declare @separator as char(1)
set @separator='-';


declare @tabcheck as table(id int,fromval int ,toval int)
insert into @tabcheck values(1,3,3),(2,1,3),(3,5,7),(4,1,2);

declare @myvalues as table(id int identity(1,1),myval varchar(100));
with cte as(
select @str [mystr],
cast(1 as int) [Start],
charindex(@separator,@str)as Nd
union all
select substring(@str,nd+1,len(@str)),cast(Nd+1 as int),charindex(@separator,@str,Nd+1) from cte
where nd>0
)
insert into @myvalues(myval) 
select case when nd>0 then substring(@str,start,Nd-start) 
else substring(@str,start,len(@str)) end [splitted] 
from cte   OPTION (MAXRECURSION 1000);

declare @result as int;
with mytab as(
select t1.id,t1.myval,len(t1.myval) L,t2.fromval,t2.toval,
case when len(t1.myval)>=t2.fromval and len(t1.myval)<=t2.toval then 1 else 0 end [result]
 from @myvalues t1 inner join @tabcheck t2 on t1.id=t2.id)
 select @result=count(1)  from mytab where result=0 ;

 select case @result when 0 then 'OK' else 'Mistake' end [result]

有可能看到您生成代码吗?您没有解释如何修复数据。如果“2-2651274-500-147”错误,正确的值应该是什么?使用拆分和LEN函数。如果长度小于3,则是错误的是用户输入此代码作为描述,如jdajshd 1-1486414-305-115这是ok代码和udab dasd,我在新列中输入代码,您打算如何修复它?好的解决方案!我还有另一个方法,它使用递归将字符串拆分为多个字符串,并检查长度是否符合条件,请查看我的解决方案,让我知道您的想法递归恐怕不是最好的解决方案,因为您可以在没有递归的情况下拆分项目。这也只检查一个值的有效性或缺少值,而不是整个表;使其更难扩展。