【问题标题】:How to fix (Arithmetic overflow error converting expression to data type datetime) error in SQL Server如何修复 SQL Server 中的(将表达式转换为数据类型日期时间的算术溢出错误)错误
【发布时间】:2019-05-27 21:19:27
【问题描述】:

我创建了一个过程,用于从 Oracle 数据库表中获取昨天的数据并将其插入到 SQL Server 2012 表中。

使用下面的

IF OBJECT_ID('tempdb..#Temp') IS NOT NULL
    DROP TABLE #Temp

SELECT   
    LEAD(CONVERT(VARCHAR, CONVERT(DATETIME, '01-JAN-1970 03:00:00', 120) + [DAT_CLOSEDATE] / (24 * 60 * 60), 120), 1, CONVERT(VARCHAR, CONVERT(DATETIME, '01-JAN-1970 03:00:00', 120) + [DAT_CLOSEDATE] / (24 * 60 * 60), 120)) OVER (PARTITION BY [TXT_TICKETNUMBER] ORDER BY [DAT_CLOSEDATE]) AS [CLOSE_DATE]
INTO #Temp
FROM OPENQUERY(ORACLE_DB, 'SELECT DAT_CLOSEDATE ,TXT_TICKETNUMBER   
                           FROM SCHEME.TABLE')
WHERE       
    [DAT_CLOSEDATE] = DATEADD(d, -1, GETDATE()) 

SELECT * FROM #Temp

当我不使用WHERE 条件时,一切都按预期工作。

但是一旦我使用WHERE条件,就会出现如下错误

消息 8115,第 16 级,状态 2,第 4 行
将表达式转换为数据类型 datetime 时出现算术溢出错误。

注意:

Oracle 表中的DAT_CLOSEDATE 列数据类型为float,它在sql server 中的日期时间。

我使用LEADCONVERT 函数将其值转换为datetime 数据类型

我已尝试将其转换为日期数据类型,如下所示。

IF OBJECT_ID('tempdb..#Temp') IS NOT NULL
    DROP TABLE #Temp

SELECT   
lead(convert(varchar,convert(date,'01-JAN-1970 03:00:00',120) + 
[DAT_CLOSEDATE]/(24*60*60), 120),1,convert(varchar,convert(date,'01-JAN-
1970 03:00:00',120) + [DAT_CLOSEDATE]/(24*60*60), 120)) over(partition by 
[TXT_TICKETNUMBER] order by [DAT_CLOSEDATE])AS  [CLOSE_DATE]
INTO #Temp
FROM OPENQUERY(ORACLE_DB, 'SELECT DAT_CLOSEDATE ,TXT_TICKETNUMBER   
                           FROM SCHEME.TABLE')
WHERE [DAT_CLOSEDATE] = DATEADD(d,-1,GETDATE()) 

SELECT * FROM #Temp

但我得到了这个错误

消息 206,第 16 级,状态 2,第 4 行
操作数类型冲突:日期与浮点数不兼容

Oracle 表中 DAT_CLOSEDTE 列的样本数据,它是 FLOAT

DAT_CLOSEDATE
1531038410
1531038433
1531038438
1531038447
1531038449
1531038450
1531038506
1531038506

我正在寻找的解决方案之一是我希望 OPENQUERY 语法类似于以下内容:

OPENQUERY(ORACLE_DB, 'SELECT DAT_CLOSEDATE, TXT_TICKETNUMBER   
FROM SCHEME.TABLE 
WHERE [DAT_CLOSEDATE] = trunc(sysdate)-1')

但需要先从FLOAT转换为DATE数据类型。

【问题讨论】:

  • 样本数据最好使用DDL + DML。请edit您的问题包括它,您当前的尝试和您想要的结果。更多详情,read this.
  • 您能否添加一些您尝试与 WHERE 子句中的当前日期进行比较的 DAT_CLOSEDATE 浮点示例值?
  • “oracle 表中的 DAT_CLOSEDATE 列数据类型是浮点数。” 我不想问,但为什么呢?如果是日期,为什么将其存储为float? Oracle 和 SQL Server 以及日期和时间数据类型。
  • @Gambos 您可以更改 OPEN QUERY 上的 oracle 内部查询以更改数据类型或在 oracle 端创建视图,然后插入子句最简单:)。 Soo,如果您可以提供相关的示例数据,我们可以尝试重现这些错误并很高兴为您提供帮助。

标签: sql-server oracle oracle11g ddl dml


【解决方案1】:

这是一个示例 sn-p,它使用额外的子查询将 FLOAT 转换为 DATETIME。
这使得进一步的计算更容易。

因为它是一个示例,所以不使用插入临时表。

declare @Table table (TXT_TICKETNUMBER VARCHAR(30), DAT_CLOSEDATE FLOAT);

insert into @Table (TXT_TICKETNUMBER, DAT_CLOSEDATE) values
('foo000042', ((CONVERT(float, DATEADD(hour,-24,GETDATE()))*86400.0)-(25567.0*86400))), 
('foo000042', ((CONVERT(float, DATEADD(hour,-23,GETDATE()))*86400.0)-(25567.0*86400))),
('bar000042', ((CONVERT(float, DATEADD(hour,-22,GETDATE()))*86400.0)-(25567.0*86400))), 
('bar000042', ((CONVERT(float, DATEADD(hour,-21,GETDATE()))*86400.0)-(25567.0*86400)));

SELECT
TICKETNUMBER, 
CLOSEDATETIME,
DAT_CLOSEDATE,
LEAD(CloseDatetime) OVER (PARTITION BY TICKETNUMBER ORDER BY CLOSEDATETIME) AS NextCLOSEDATETIME
FROM
(
    select 
     TXT_TICKETNUMBER AS TICKETNUMBER, 
     DATEADD(hour,3,CONVERT(datetime,25567.0+(DAT_CLOSEDATE/86400.0))) AS CLOSEDATETIME,
     DAT_CLOSEDATE
    from 
    (
        -- put the openquery here instead
        select TXT_TICKETNUMBER, DAT_CLOSEDATE 
        from @Table
    ) q1
) q2
WHERE CAST(CLOSEDATETIME AS DATE) = CAST(DATEADD(day,-1,GETDATE()) AS DATE)

但是,如果您更改该 Oracle 查询以将“DAT_CLOSEDATE”转换为字符串。
例如YYYY-MM-DD HH24:MI:SS 格式。
那么这可能会使转换为 T-SQL DATETIME 变得更容易一些。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多