SQL:替换包含在文本字符串中的日期

SQL:替换包含在文本字符串中的日期,sql,sql-server,replace,Sql,Sql Server,Replace,我正在使用SQL Server Management Studio 2012。我处理医疗记录,需要取消识别报告。报告在一个表中结构化,表中包含列“报告日期”、“报告主题”、“报告文本”等。。。我需要更新的字符串在报告文本中,有大约700000条记录 因此,如果我有: "patient had an EKG on 04/09/2012" 我需要将其替换为: "patient had an EKG on [DEIDENTIFIED]" 我试过了 UPDATE table SET Report

我正在使用SQL Server Management Studio 2012。我处理医疗记录,需要取消识别报告。报告在一个表中结构化,表中包含列“报告日期”、“报告主题”、“报告文本”等。。。我需要更新的字符串在报告文本中,有大约700000条记录

因此,如果我有:

"patient had an EKG on 04/09/2012" 
我需要将其替换为:

"patient had an EKG on [DEIDENTIFIED]"
我试过了

UPDATE table 
SET Report_Text = REPLACE(Report_Text, '____/___/____', '[DEIDENTIFED]')
因为我需要替换其中任何看起来像日期的东西,它运行但实际上不替换任何东西,因为显然我不能在这个命令中使用u通配符


对此有何建议?提前谢谢

为了简单起见,假设一个数字代表字符串中的一个标识元素,那么查找字符串中第一个数字的位置和最后一个数字的位置。不确定这是否适用于您的整个记录集,但以下是代码

我创建了两个测试字符串。。。一个是您提供的,另一个是字符串开头的日期

Declare @tstString varchar(100)
Set @tstString = 'patient had an EKG on 04/09/2012'
Set @tstString = '04/09/2012 EKG for patient'

Select @tstString
-- Calculate 1st Occurrence of a Number
,PATINDEX('%[0-9]%',@tstString)
-- Calculate last Occurrence of a Number
,LEN(@tstString) - PATINDEX('%[0-9]%',REVERSE(@tstString))

,CASE
    -- No numbers in the string, return the string
    WHEN PATINDEX('%[0-9]%',@tstString) = 0 THEN @tstString

    -- Number is the first character to find the last position and remove front
    WHEN PATINDEX('%[0-9]%',@tstString) = 1 THEN 
        CONCAT('[DEIDENTIFIED]',SUBSTRING(@tstString, LEN(@tstString)-PATINDEX('%[0-9]%',REVERSE(@tstString))+2,LEN(@tstString)))

    -- Just select string up to the first number
    ELSE CONCAT(SUBSTRING(@tstString,1,PATINDEX('%[0-9]%',@tstString)-1),'[DEIDENTIFIED]')
    END AS 'newString'
正如您所看到的,这在SQL中是混乱的。
我宁愿使用解析器服务来实现这一点,并使用SSI移动数据并调用该服务。

为了简单起见,假设一个数字代表字符串中的标识元素,因此查找字符串中第一个数字的位置和最后一个数字的位置。不确定这是否适用于您的整个记录集,但以下是代码

我创建了两个测试字符串。。。一个是您提供的,另一个是字符串开头的日期

Declare @tstString varchar(100)
Set @tstString = 'patient had an EKG on 04/09/2012'
Set @tstString = '04/09/2012 EKG for patient'

Select @tstString
-- Calculate 1st Occurrence of a Number
,PATINDEX('%[0-9]%',@tstString)
-- Calculate last Occurrence of a Number
,LEN(@tstString) - PATINDEX('%[0-9]%',REVERSE(@tstString))

,CASE
    -- No numbers in the string, return the string
    WHEN PATINDEX('%[0-9]%',@tstString) = 0 THEN @tstString

    -- Number is the first character to find the last position and remove front
    WHEN PATINDEX('%[0-9]%',@tstString) = 1 THEN 
        CONCAT('[DEIDENTIFIED]',SUBSTRING(@tstString, LEN(@tstString)-PATINDEX('%[0-9]%',REVERSE(@tstString))+2,LEN(@tstString)))

    -- Just select string up to the first number
    ELSE CONCAT(SUBSTRING(@tstString,1,PATINDEX('%[0-9]%',@tstString)-1),'[DEIDENTIFIED]')
    END AS 'newString'
正如您所看到的,这在SQL中是混乱的。
我宁愿使用解析器服务来实现这一点,并使用SSI移动数据并调用服务。

您可以使用
PATINDEX
查找日期的位置,然后使用
子字符串
替换
来替换日期

由于文本中可能有多个日期,因此必须运行while循环来替换所有日期

以下sql将以MM/DD/YYYY的形式适用于所有日期

WHILE EXISTS( SELECT 1  FROM  dbo.MyTable WHERE  PATINDEX('%[0-9][0-9]/[0-9][0-9]/[0-9][0-9][0-9][0-9]%',Report_Text) > 0 )

BEGIN

    UPDATE  t
    SET     Report_Text = REPLACE(Report_Text, DateToBeReplaced, '[DEIDENTIFIED]')
    FROM    ( SELECT    * ,
                        SUBSTRING(Report_Text,PATINDEX('%[0-9][0-9]/[0-9][0-9]/[0-9][0-9][0-9][0-9]%',Report_Text), 10) AS DateToBeReplaced
              FROM      dbo.MyTable AS a
              WHERE     PATINDEX('%[0-9][0-9]/[0-9][0-9]/[0-9][0-9][0-9][0-9]%',Report_Text) > 0
            ) AS t

END

我已经在一个只有几行的虚拟表上测试了上述sql。我不知道它将如何扩展您的数据,但建议您尝试一下。

您可以使用
PATINDEX
查找日期的位置,然后使用
子字符串
替换
替换日期

由于文本中可能有多个日期,因此必须运行while循环来替换所有日期

以下sql将以MM/DD/YYYY的形式适用于所有日期

WHILE EXISTS( SELECT 1  FROM  dbo.MyTable WHERE  PATINDEX('%[0-9][0-9]/[0-9][0-9]/[0-9][0-9][0-9][0-9]%',Report_Text) > 0 )

BEGIN

    UPDATE  t
    SET     Report_Text = REPLACE(Report_Text, DateToBeReplaced, '[DEIDENTIFIED]')
    FROM    ( SELECT    * ,
                        SUBSTRING(Report_Text,PATINDEX('%[0-9][0-9]/[0-9][0-9]/[0-9][0-9][0-9][0-9]%',Report_Text), 10) AS DateToBeReplaced
              FROM      dbo.MyTable AS a
              WHERE     PATINDEX('%[0-9][0-9]/[0-9][0-9]/[0-9][0-9][0-9][0-9]%',Report_Text) > 0
            ) AS t

END

我已经在一个只有几行的虚拟表上测试了上述sql。我不知道它将如何为您的数据扩展,但建议您尝试一下。

很抱歉没有尽快回复您!非常感谢你的帮助。为了确保这个解决方案在我的整个表格中都有效:本文档中的文本变化很大;充满了日期,可以在文本中的任何地方找到,通常不在任何可预测的上下文中。这个解决方案会在任何地方找到日期并替换它吗?或者我的声明需要像你这里的例子一样具体吗?再次感谢您。将一些示例放入@tstString变量中,您将看到结果。它确实会找到日期,但我认为它会截断字符串并添加[DEIDENTIFIED]。因此,它将查找日期,但不会显示整个文本。当日期出现在中间时,您将不得不添加另一个WHON子句来处理。很抱歉没有尽早回复您!非常感谢你的帮助。为了确保这个解决方案在我的整个表格中都有效:本文档中的文本变化很大;充满了日期,可以在文本中的任何地方找到,通常不在任何可预测的上下文中。这个解决方案会在任何地方找到日期并替换它吗?或者我的声明需要像你这里的例子一样具体吗?再次感谢您。将一些示例放入@tstString变量中,您将看到结果。它确实会找到日期,但我认为它会截断字符串并添加[DEIDENTIFIED]。因此,它将查找日期,但不会显示整个文本。当日期出现在中间时,必须添加另一个WHON子句来处理。