将float转换为datetime

kab*_*han 1 sql-server

我有一个FLOAT日期字段,如下所示:

+-----------+
| FloatDate |
+-----------+
| 1012013   | -- Jan 1
| 3262013   | -- Mar 26
| 11072013  | -- Nov 7
| 10012013  | -- Oct 1
+-----------+
Run Code Online (Sandbox Code Playgroud)

我想将此数据插入另一个表,其dateField的数据类型是DATETIME.

所以,我正在尝试将FloatDate值转换为DATETIME,但我只是保持失败..

我试过了

INSERT INTO NEWTABLE 
(DateTimeDate)
SELECT CONVERT(DATETIME, CAST(CAST(FloatDate AS INTEGER) AS CHAR), 112)
FROM OLDTABLE
Run Code Online (Sandbox Code Playgroud)

但这给了我一个错误

从字符串转换datetime时转换失败

如果FloatDate的日期格式为YYYYMMDD,它似乎有效.所以,如果我这样做,它就有效.

DECLARE @test FLOAT
SET @test = 2132013                                                                                                                            
SELECT @test,  CONVERT(DATETIME, CAST(RIGHT(CAST(@test AS INTEGER), 4) AS CHAR(4)) + 
CASE WHEN LEN(CAST(@test AS INTEGER)) = 7 THEN '0' + CAST(LEFT(CAST(@test AS INTEGER), 3) AS CHAR(3))
     WHEN LEN(CAST(@test AS INTEGER)) = 8 THEN CAST(LEFT(CAST(@test AS INTEGER), 4) AS CHAR(4)) END, 1)
Run Code Online (Sandbox Code Playgroud)

但是,我想知道我是否让这个太复杂,只是错过了更简单的解决方案,或者这是我能实现的唯一方法?

Aar*_*and 7

假设您有其他值,例如:

 3092013 -- March 9th
10052013 -- October 5th
 1112013 -- January 11th
11012013 -- November 1st
Run Code Online (Sandbox Code Playgroud)

然后你可以这样做:

DECLARE @x TABLE(FloatDate FLOAT);

INSERT @x VALUES
( 3092013),-- -- March 9th
(10052013),-- -- October 5th
( 1112013),-- -- January 11th
(11012013);-- -- November 1st

;WITH s(d) AS (SELECT RIGHT('0' + CONVERT(VARCHAR(32), 
  CONVERT(INT, FloatDate)), 8) FROM @x),
d(d) AS (SELECT CONVERT(DATETIME, 
  RIGHT(d,4) + LEFT(d,2) + SUBSTRING(d,3,2)) FROM s)
SELECT d FROM d;
Run Code Online (Sandbox Code Playgroud)

结果:

d
-----------------------
2013-03-09 00:00:00.000
2013-10-05 00:00:00.000
2013-01-11 00:00:00.000
2013-11-01 00:00:00.000
Run Code Online (Sandbox Code Playgroud)

在您的示例中,它将是:

;WITH s(d) AS (SELECT RIGHT('0' + CONVERT(VARCHAR(32), 
  CONVERT(INT, FloatDate)), 8) FROM dbo.OLDTABLE),
d(d) AS (SELECT CONVERT(DATETIME, 
  RIGHT(d,4) + LEFT(d,2) + SUBSTRING(d,3,2)) FROM s)
INSERT dbo.NEWTABLE
SELECT d FROM d;
Run Code Online (Sandbox Code Playgroud)

当然,即使您获得了有效值的语法,也可能会有一些不良数据.由于您使用过FLOAT您没有获得任何固有的验证,因此该列可能包含-99945671213等.

你觉得这很痛苦吗?好!它应该是痛苦的.你应该回到那些决定在一个FLOAT专栏中存储日期并将其踢入胫骨的人.询问他们是否使用地理数据类型存储工资.我很高兴您正在解决这个问题,但不应该允许这些人接近数据库设计.

最后,请不要这样做:

CAST(anything AS CHAR)
Run Code Online (Sandbox Code Playgroud)

始终指定长度.原因如下:

  • 我通常将所有XML数据保存在字节编码的bigint列中,我还建议将最多32个BIT列打包成INT值(节省时间和空间!) (2认同)