2012-09-21 35 views
2

截图解释了这一切。 http://i46.tinypic.com/f3hobl.png从字母数字字段中提取6-8位数字的日期

在当前的配置,InvoiceSentDate只接受8位日期(MM-DD-YY)。我希望能够捕捉MM-DD-YYYY日期。我该怎么做呢?

为了进行比较,看看发票2106至2112年VS 2116

此外,使事情变得复杂!有些记录在日期后有文字。 http://i50.tinypic.com/2r5qa88.png

+0

这会在任务SSIS,我知道该怎么做。现在,我只是想构建能够清楚地获取日期的SQL语句。 – Kyle

+1

这将推动TSQL将直接做什么。你可能需要CLR和正则表达式。 – Paparazzi

+1

我也正在建议CLR和正则表达式。 http://msdn.microsoft.com/en-us/magazine/cc163473.aspx#S2 – CandiedCode

回答

4

可以在纯T-SQL做到这一点。这是工作SqlFiddle

在这里,我找到patindex的日期,然后找到之后的第一个非数字。这给出了substring需要的参数来单独提取日期。如您所见,我添加了一些涵盖各种可能性的测试数据,包括斜线和短划线日期分隔符。

-- Test data 
declare @Demo table (
    RawData varchar(100) null 
) 
insert into @Demo select 'JS sent via Unifier on 08/29/2012' 
insert into @Demo select 'i sent via email on 09/07/12' 
insert into @Demo select 'i sent via Unifier on 01/04/12; resubmitting p...' 
insert into @Demo select 'JS sent via Unifier on 08-29-2012; resubmitting p...' 
insert into @Demo select '08-29-2012; resubmitting p...' 
insert into @Demo select '08-29-12' 
insert into @Demo select 'no date here' 
insert into @Demo select null 

-- Actual query 
select *, 
    -- If there's a date, display it 
    case when StartChar > 0 then substring(RawData, StartChar, DateLen) else null end as DateString 
from (
    select *, 
     -- Find the first date 
     patindex('%[0-1][0-9][/-][0-3][0-9][/-][0-9][0-9]%', RawData) as StartChar, 
     -- Find the first non-digit after that date 
     patindex(
      '%[^0-9]%', 
      right(
       RawData + '_', -- This underscore adds at least one non-digit to find 
       len(RawData) - patindex('%[0-1][0-9][/-][0-3][0-9][/-][0-9][0-9]%', RawData) - 6 
      ) 
     ) + 7 as DateLen 
    from @Demo 
) as a 

更新

如果你只是寻找两个可能的日期格式,你可以查询一定程度上受到只是检查他们简单:

select *, 
    -- If there's a date, display it 
    case 
     when StartChar1 > 0 then substring(RawData, StartChar1, 10) 
     when StartChar2 > 0 then substring(RawData, StartChar2, 8) 
     else null 
    end as DateString 
from (
    select *, 
     -- Find the first MM-DD-YYYY 
     patindex('%[0-1][0-9][/-][0-3][0-9][/-][0-9][0-9][0-9][0-9]%', RawData) as StartChar1, 
     -- Find the first MM-DD-YY 
     patindex('%[0-1][0-9][/-][0-3][0-9][/-][0-9][0-9]%', RawData) as StartChar2 
    from @Demo 
) as a 
+0

非常感谢!您的答案与我的数据集非常吻合。 – Kyle

1

CndiedCode链接中的示例非常接近您需要的示例。

只是稍微不同的正则表达式匹配

N '^ \ d {3} - \ d {2} - \ d {4} $'
进入
N'\ d {2}/\ d {2}/\ d {2,4}”

下面的代码看起来不同,因为不得不逃离\

if (Regex.IsMatch("sent on 01/01/10; ex", "\\d{2}/\\d{2}/\\d{2,4}")) 
    { 
     System.Diagnostics.Debug.WriteLine(Regex.Match("sent on 01/01/10; ex", "\\d{2}/\\d{2}/\\d{2,4}")); 
    } 
    if (Regex.IsMatch("sent on 01/01/2012; ex", "\\d{2}/\\d{2}/\\d{2,4}")) 
    { 
     System.Diagnostics.Debug.WriteLine(Regex.Match("sent on 01/01/2012; ex", "\\d{2}/\\d{2}/\\d{2,4}")); 
    } 
+0

从Tim的答案似乎是一个纯粹的TSQL +1。如果事情变得更复杂,那么你需要冒险进入正则表达式。 – Paparazzi

+0

我是SSIS的新手,很想看看正则表达式是如何完成的。看起来像一些强大的,有用的东西。你能证明这一点吗? – Kyle

+0

我不是专家,所以我所能做的就是将你指向我参考的地方http://www.regular-expressions.info/如果你打算处理数据解析,那么它就是你需要的工具在你的腰带上。 – Paparazzi