SQL字符串替换日期

时间:2018-09-28 13:20:40

标签: sql date replace sql-server-2012

我有一个并不总是相同的字符串文件名,我正在努力提出一些干净且不太笨拙的东西,这些东西会去除the的日期部分,并用yyyyMMdd或yyMMdd替换(取决于文件名字符串格式)。

例如,文件名看起来像这样:

g_monthlysales_20130930_2500g.txt

我想将其转换为此:

g_monthlysales_yyyyMMdd_2500g.txt

或者文件名看起来像这样:

gx130930rtwtg.txt

我想将其转换为此:

 gxyyMMddrtwtg.txt

这是文件名仅有的两种日期格式,大多数情况下,日期位于同一位置,但其他文件名字符将不同,例如,我也有sx141001theuf.txth_monthlysales_20130930_1000v.txt

非常感谢您的帮助。

3 个答案:

答案 0 :(得分:0)

如果日期总是在同一位置,文件总是在相同格式,则此代码应该起作用:

declare @testString nvarchar(100)
declare @result nvarchar(100)

set @testString = 'h_monthlysales_20130930_1000v.txt'
-- set @testString = 'g_monthlysales_20130930_2500g.txt'
-- set @testString = 'gx130930rtwtg.txt'
-- set @testString = 'sx141001theuf.txt'

IF patindex('_______________[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]_[0-9][0-9][0-9][0-9]_.txt',@testString) = 1
BEGIN
    set @result = SUBSTRING(@testString,1,15)+'yyyyMMdd'+SUBSTRING(@testString,24,100)
END
ELSE IF patindex('__[0-9][0-9][0-9][0-9][0-9][0-9]_____.txt',@testString) = 1
BEGIN
    set @result = SUBSTRING(@testString,1,2)+'yyMMdd'+SUBSTRING(@testString,9,100)
END
ELSE
BEGIN
    set @result = @testString
END

print @result

如果日期可以更改位置,则如果日期始终是第一个数字值(对于第二个日期格式,请编写类似的代码),则将执行类似的操作:

declare @testString nvarchar(100)
declare @result nvarchar(100)
declare @datePostion int

--set @testString = 'h_monthlysales_20130930_1000v.txt'
set @testString = 'g_monthlysalesxyz_20130930_2500g.txt'

set @datePostion = patindex('%[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]%.txt',@testString)
IF @datePostion > 0
BEGIN   
    set @result = SUBSTRING(@testString,1,@datePostion-1)+'yyyyMMdd'+SUBSTRING(@testString,@datePostion+8,100)
END
ELSE
BEGIN
    set @result = @testString
END

print @result 

答案 1 :(得分:0)

这将首先找到任何8位数字,然后再找到6位数字,然后尝试将其转换为date值。尽管几乎可以肯定,它可以处理文件名中任何地方的日期,但效果肯定会如此:

declare @t table(f varchar(50));
insert into @t values('g_monthlysales_20130930_2500g.txt'),('gx130930rtwtg.txt'),('sx141001theuf.txt'),('h_monthlysales_20130930_1000v.txt');

select f
      ,case when patindex('%[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]%',f) > 0
            then convert(date,substring(f,patindex('%[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]%',f),8),112)
            else convert(date,substring(f,patindex('%[0-9][0-9][0-9][0-9][0-9][0-9]%',f),6),12)
            end as d
from @t;

输出:

+-----------------------------------+------------+
|                 f                 |      d     |
+-----------------------------------+------------+
| g_monthlysales_20130930_2500g.txt | 30.09.2013 |
| gx130930rtwtg.txt                 | 30.09.2013 |
| sx141001theuf.txt                 | 01.10.2014 |
| h_monthlysales_20130930_1000v.txt | 30.09.2013 |
+-----------------------------------+------------+

如果您可以找到所有可能的格式,或者更好地将导入例程更改为具有一致的文件名格式,则可以通过缺少必需的通配符来使此查询更高效。

答案 2 :(得分:0)

如果我正确地阅读了该问题,则不是在尝试隔离日期,而是在尝试覆盖它们。这应该可以做到,或者让您始终朝着这个方向前进。

parseFloat()

结果:

DECLARE @t TABLE (FileNme VARCHAR(50));
INSERT INTO
  @t
VALUES
  ('g_monthlysales_20130930_2500g.txt')
 ,('gx130930rtwtg.txt')
 ,('sx141001theuf.txt')
 ,('h_monthlysales_20130930_1000v.txt');

SELECT
  FileNme
 ,CASE
    WHEN PATINDEX('%[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]%', FileNme) > 0 
      THEN STUFF(FileNme, PATINDEX('%[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]%', FileNme), 8, 'yyyyMMdd')
    ELSE STUFF(FileNme, PATINDEX('%[0-9][0-9][0-9][0-9][0-9][0-9]%', FileNme), 6, 'yyMMdd')
  END AS NewNme
FROM
  @t;