【问题标题】:Find records where string values are similar查找字符串值相似的记录
【发布时间】:2019-10-21 20:18:27
【问题描述】:

我正在汇总错误以跟踪记录的错误总数。我目前正在尝试创建一个查询,以查找/分组几条具有相似值的记录,以便将它们记录为一个错误而不是几个单独的错误。唯一的区别是 id 或 2,这就是它们被分组的原因。数据库通过应用洞察和分析流从我们的系统中注入错误。我有一个包含“模板”错误的表,用于查找和分组这些特定错误。并非所有记录的错误都需要模板,因为它们被适当地分组,因为它们完全相同。当尝试使用 like 来查找错误时,似乎很难使用破折号。我很难找到信息来帮助我解决这个问题。我尝试使用替换来删除破折号,但这不起作用,因为错误太长了。

示例模板:

Auto Resubmit for % failed with ' Object reference not set to an instance of an object. '

示例错误:

Auto Resubmit for 004e9e2d-3704-4cfd-a90d-42520203df79 - 18723191 failed with ' Object reference not set to an instance of an object. '

Auto Resubmit for 0130e64e-64e6-4a23-88a4-51fba823705b - 18734821 failed with ' Object reference not set to an instance of an object. '

Auto Resubmit for 11809bf5672f4e98987119dbd06e5d78 - 17359076 failed with ' Object reference not set to an instance of an object. '

示例查询:

select top 1000 * from errorTable where error like 'Auto Resubmit for % failed with '' Object reference not set to an instance of an object.'

【问题讨论】:

  • 请向我们展示您当前的查询,让我们知道它有什么问题。
  • 现在,我只是想查找记录,所以查询没有什么特别之处。
  • 如果将查询中的%替换为表中存在的id,会返回对应的记录吗?
  • 把你的逻辑分成几部分。您无需尝试查找模板值,因为您无法神奇地替换/忽略占位符。您想要以“自动重新提交”开头的行。然后您想进一步过滤那些包含“对象引用未设置为对象实例”的行。试一试逻辑。
  • 分解逻辑确实有效,但是,并非所有错误看起来都像我提供的这个特定错误。 id 和 guid 可以在消息中的任何位置。 (例如,itemid2 的自动重新提交 - 18137385 失败,出现“访问被拒绝:userId='12602174'”)要尝试分解它,我认为逻辑会有点复杂。

标签: sql-server azure-sql-database sql-like


【解决方案1】:

如果唯一不同的是参数值,您可以在存储/检查字符串之前对其进行规范化。周围有很多实用程序可以做到这一点。一个例子是我们免费的 SDU 工具中的 ExtractSQLTemplate 函数。您不需要使用该工具包。只需获取该函数的代码作为示例。你可以在这里看到它:https://youtu.be/yX5q00m_uCA

另一种选择是在字符串上使用全文索引。您可以使用 FREETEXTTABLE 和/或 FREETEXT 等函数来查找字符串之间的相似性。

【讨论】:

    【解决方案2】:

    您无法使用Template Table 的主要原因之一是您以这种方式存储错误基本上没有达到模板的目的。

    换句话说,您的表不是Normalize,也不是任何relation 之间的定义 2 张桌子。

    Auto Resubmit for 004e9e2d-3704-4cfd-a90d-42520203df79 - 18723191 failed with 
    ' Object reference not set to an instance of an object. '
    

    你的错误表设计应该是这样的,

    TemplateID -- id column of Template table
    Module -- Name of module from where error originated
    SubmoduleName-- Method name
    ErrorMessage-- Original error message like "Object reference not set to an instance of an object".
    CustomError -- Auto Resubmit for 004e9e2d-3704-4cfd-a90d-42520203df79 - 18723191 failed with
    

    通过这种方式,您可以使用ErrorMessage 列轻松地将Template TableError Table 连接起来。

    ErrorMessage : It should always contain original message thrown by `exception`.
    

    您可以根据自己的要求自定义错误表。只需一点点努力。

    如果您可以将TemplateID (FK) 存储在Error 表中,那就太好了。 所有问题都会立即消失。

    简而言之,以一种无需字符串操作即可轻松连接它们的方式保存表格。

    目前尚不清楚,% 将以什么模式被替换。

    创建表#Template(Templateid int identity(1,1),Template varchar(500)) 插入#Template 值('Auto Resubmit for % failed with ''Object reference not set to an instance of an object.'')

    --从#Template中选择*

    create table #ErrorLog(Errorid int identity(1,1),ErrorMessage varchar(500))
     insert into #ErrorLog values
    ('Auto Resubmit for 004e9e2d-3704-4cfd-a90d-42520203df79 - 18723191 failed with ''Object reference not set to an instance of an object.''')
    ,('Auto Resubmit for 0130e64e-64e6-4a23-88a4-51fba823705b - 18734821 failed with ''Object reference not set to an instance of an object.''')
    ,('Auto Resubmit for 11809bf5672f4e98987119dbd06e5d78 - 17359076 failed with ''Object reference not set to an instance of an object.''' )
    ,('Auto Resubmit for itemid2 - 18137385 failed with '' Access Denied: userId=''12602174''' )
    

    使用任何split string 函数将模板表拆分为'%' 并将其存储在#temp 表中

    create table #temp(Errorid int identity(1,1),ErrMsg varchar(500),rownum int)
    
    insert into #temp
    select value,row_number()over(order by (Select null))rn from #Template t
    cross apply(select replace(value,'failed with','')value from string_split(t.Template,'%'))ca
    
    
    
    select t1.* from
    (
    select el.ErrorMessage,c.ErrMsg,c.rownum from  #ErrorLog EL 
    inner join  #temp c on  el.ErrorMessage like '%' +ErrMsg+'%' and c.rownum=1
    )t1
    inner join  #temp c1 on  t1.ErrorMessage like '%' +ltrim(c1.ErrMsg)+'%' and c1.rownum=2
    
    
    select * from #temp
    drop table #Template,#ErrorLog,#temp
    

    事实上,为了编写近乎完美的查询 1 需要分析数据并为其编写尽可能多的测试用例。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-05-06
      • 1970-01-01
      • 1970-01-01
      • 2011-03-20
      • 2016-11-28
      • 1970-01-01
      • 2012-06-30
      相关资源
      最近更新 更多