【问题标题】:Regex or conversion for 'YYYY-MMM-DD''YYYY-MMM-DD' 的正则表达式或转换
【发布时间】:2020-03-30 22:12:08
【问题描述】:

我正在处理t-SQL 中的数据,为了使SSIS 中的包自动化处理每个给定日期的每个文件,我需要找出regex 或文件的转换,例如'leads_2019-Dec-22',以便打包完成。

到目前为止,这就是我所知道的,但这仅适用于'YYYY-MM-DD' 格式。我无法通过我拥有的数据加载器工具更改格式,因此没有简单的解决方法。

@[User::UploadedFile] = 
REPLACE(REPLACE(REPLACE(REPLACE(@[User::UploadedFileName], "yyyy", 
(DT_STR,4,1252)DATEPART( "yyyy" , getdate())),"mm",RIGHT("0"+ 
(DT_STR,4,1252)DATEPART("mm",getdate()),2)), "dd", RIGHT("0"+ 
(DT_STR,4,1252)DATEPART("dd",getdate()),2)), "hh",  right("0" + 
(DT_STR,4,1252)DATEPART("Hh",getdate()),2)             )

之前有没有人处理过这个问题,如果有,您是如何/将如何使用表达式解决这个问题的?

【问题讨论】:

  • 日期是否总是相同的格式?
  • 据我所知,ms sql 中没有regexes。不过,您可以搜索 SO 寻找解决方案。
  • 如果要将日期转换为 yyyy-mm-dd,则只需使用正确的转换代码将日期转换为 varchar。只需查找 sql 日期转换代码以找到正确的代码,并在需要时截断或替换空格等字符。
  • 你能解释一下(DT_STR,4,1252)的意义吗?
  • yyyy-mm-dd 是 ISO8601。 CONVERT( VARCHAR(10), GETDATE(), 23 ) 应该可以解决问题。见docs.microsoft.com/en-us/sql/t-sql/functions/…

标签: sql sql-server regex tsql ssis


【解决方案1】:

SQL Server 不支持正则表达式。
但是,文件名中使用的格式与您可以使用 convert 从字符串表示中获取实际日期的格式非常相似。

106 样式下支持的格式转换是dd mom yyyy - 这意味着您所要做的就是将日期部分从字符串中分离出来,用空格替换连字符,然后进行转换。

请注意,如果当前登录的默认语言不是英语,您可能会收到错误,因为月份名称取决于语言设置。
这就是我在代码中包含set language 语句的原因:

SET LANGUAGE us_english;

DECLARE @FileName varchar(20) = 'leads_2019-Dec-22';

SELECT CONVERT(Date, REPLACE(RIGHT(@FileName, 11), '-', ' '), 106);

结果:

2019-12-22 

【讨论】:

  • SQL-Server 不允许正则表达式,但 SSIS 允许。
【解决方案2】:

如果您现在和永远可以确定,这将永远不会在具有不同文化的系统中运行,您可以使用简单的转换或专门为会话设置语言和文化。

但是 - 如果曾经在不同的系统上运行 - 这可能会通过您所有的内部测试,并且可能会因愚蠢的错误而中断生产。

特定于文化的方法(更糟糕的是:特定于语言的方法)非常危险......

要克服这个问题,您可以使用以下文化安全的方法(但它会比简单的转换慢):

--Your question is not clear for me about the actual input.
--The string I use here seems to be your needed outcome...
--However, you will get the ghist how you can approach this issue with any given value...  
DECLARE @TheFileName varchar(20) = 'leads_2019-Dec-22';

--not needed, just for testing... (in Germany "Dec" needs to be "Dez"...)
SET LANGUAGE GERMAN;

SELECT FORMAT(TRY_PARSE(RIGHT(@TheFileName,11) AS DATE USING 'en-us'),'yyyy-MMM-dd','en-us');

你有三个障碍:

首先是切断纯日期。我通过使用 RIGHT 来做到这一点,假设我们总是需要最右边的 11 个字符。
其次是从中获取日期类型的值。 TRY_PARSE() 接受文化参数以确保正确阅读。
第三是创造正确的输出。这里我使用FORMAT(),它再次允许特定的文化。

【讨论】:

    【解决方案3】:

    假设您想要来自名为 UploadedFileName 的变量的 YYYY-MM-DD 格式的输出字符串,该变量具有 'leads_2019-Dec-22' 等数据,您只需替换“leads_”部分并转换剩下的约会。然后就可以解析日期改成想要的YYYY-MM-DD格式:

    (DT_WSTR, 4) YEAR((DT_DATE) REPLACE(@[User::UploadedFileName],"leads_","")) + "-" +
    (DT_WSTR, 2) MONTH((DT_DATE) REPLACE(@[User::UploadedFileName],"leads_","")) + "-" +
    (DT_WSTR, 2) DAY((DT_DATE) REPLACE(@[User::UploadedFileName],"leads_",""))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-12
      • 1970-01-01
      相关资源
      最近更新 更多