【问题标题】:how to check and change custom string in sql server如何在sql server中检查和更改自定义字符串
【发布时间】:2019-04-23 22:41:06
【问题描述】:

我的 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

如何检查和修复错误代码。

感谢阅读我的问题

【问题讨论】:

  • 是否可以看到您生成代码?
  • 你没有解释如何修复数据。如果'2-2651274-500-147' 是错误的,那么正确的值应该是多少?
  • 使用 SPLIT 和 LEN 函数。如果 Length 小于 3 则错误
  • 是的,用户输入此代码进行描述,例如 jdajshd 1-1486414-305-115,这是可以的代码和 udab dasd,我在新列中输入了代码
  • 你打算如何修复它?

标签: sql sql-server


【解决方案1】:

或者,您可以拆分部分并检查它们的长度,而不是加载 LIKE 表达式,然后通过检查字符串是否仅包含带有 LIKE 的数字和连字符来跟进。由于您的字符串具体有 4 个部分,因此我在这里使用了 PARSENAME,而不是“拆分器”函数。

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 '\';

【讨论】:

  • 很好的解决方案!我还有另一个使用递归将字符串拆分为多个字符串并检查长度是否符合条件的方法,请查看我的解决方案并让我知道您的想法
【解决方案2】:

多么痛苦,因为 SQL Server 不支持正则表达式。

一种方法是 6 次 like 比较:

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

【讨论】:

    【解决方案3】:

    这是可以达到所需结果的完整代码

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

    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]
    

    【讨论】:

    • 恐怕递归不是最好的解决方案,当你可以在没有它的情况下拆分项目时。这也只检查一个值的有效性(或缺乏),而不是整个表;使其更难扩展。
    猜你喜欢
    • 2012-01-29
    • 2020-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多