SQL Server算术溢出错误 - 将nvarchar转换为datetime

时间:2016-11-30 12:29:52

标签: sql sql-server datetime sqldatatypes

我正在从视图中检索数据,而我正在使用的其中一列是nvarchar(50),但只有N'True'N'False',具体取决于操作此父视图中的相关日期列。

以下代码检索记录ID和我要查找的列YTD

SELECT Enquiry_Number, YTD 
FROM dbo.vw_SalesPO_YTD

输出:

ENQ-001 True
ENQ-002 False
ENQ-003 True

但是,出于某种原因,我无法使用此YTD列过滤我的结果。如果我试图这样做:

SELECT Enquiry_Number, YTD
FROM dbo.vw_SalesPO_YTD
WHERE YTD = N'True'

然后失败并出现以下错误:

  

将表达式转换为数据类型datetime的算术溢出错误。

我不明白,因为此查询中没有datetime个表达式。是的TrueFalse是通过比较父视图中的日期时间来确定的,但我不明白这可能会如何渗透到此子查询中。在父视图中尝试相同的操作会产生相同的错误 - 为了简单起见,我正在以这种方式展示它。

但是,在查询的SELECT部分执行类似的操作可以正常运行:

SELECT 
    Enquiry_Number,
    YTD,
    CASE 
       WHEN YTD = N'True' THEN 1 ELSE 0 
    END As C
FROM
    dbo.vw_SalesPO_YTD 

输出:

ENQ-001 True 1
ENQ-002 False 0
ENQ-003 True 1

然而,这些1和0继承了相同的缺陷,我不能在WHERE子句中使用它们而不会出现此日期时间错误。

我一直在努力寻找并且不确定如何识别核心问题。我一直在阅读有关Collat​​ions和类型优先级的事情,但无法理解为什么会发生这种情况。

当我在YTD中检查INFORMATION_SCHEMA.COLUMNS时,它确认此列与我表格中的其他列没有区别:YTDnvarchar(50),使用{ {1}}整理。

相关问题:SQL Server Arithmetic overflow error converting expression to data type datetime

问题的根源

此问题仍未解决,但如果您希望重现该问题,则父视图中的此代码必须生成此问题:

Latin1_General_CI_AS

是的,这看起来过于复杂。我们正在检查CASE WHEN Award_Date <= DATEFROMPARTS(FinancialYear - 1, 11, 1) + GETDATE() - DATEADD(year, DATEDIFF(month, '20161101', GETDATE()) / 12, '20161101') THEN N'True' ELSE N'False' END 与其关联的Award_Date,该版本从11月1日到10月31日。每条记录都已知道它所在的FinancialYear。最终目的是比较今日(2016-11-30)与去年(2015-11-30)和今年(2014-11-)的比较(2014-11-30) 30)等。

因此,代码采用今天的日期并将其与相关记录的FinancialYear相结合,并在该财务年度开始与今天之间发出记录。同一年。它正在成功地做到这一点,但是我不能对它产生的FinancialYearN'True'做任何事情。

5 个答案:

答案 0 :(得分:0)

我不知道YTD源的类型是什么。

尝试使用以下内容:

SELECT Enquiry_Number, [YTD] FROM (
    SELECT Enquiry_Number, CONVERT(nvarchar(10),YTD) AS [YTD] FROM dbo.vw_SalesPO_YTD
) AS A
WHERE A.YTD = N'True'

10只是一个砰砰砰砰的价值。它将切割该区域的任何部分超过10个。这取决于您的实际字段大小。

答案 1 :(得分:0)

SELECT * FROM (SELECT Enquiry_Number, YTD FROM dbo.vw_SalesPO_YTD) AS A WHERE cast(A.YTD as varchar) = 'True'

答案 2 :(得分:0)

我使用以下作为例子:

DECLARE @Data TABLE
(
    Enquiry_Number nvarchar(10),
    YTD nvarchar(50)
)

INSERT INTO @Data(Enquiry_Number, YTD)
SELECT N'ENQ-001', N'True' UNION
SELECT N'ENQ-002', N'False' UNION
SELECT N'ENQ-003', N'True' 


SELECT Enquiry_Number, [YTD] FROM (
    SELECT Enquiry_Number, CONVERT(nvarchar(10),YTD) AS [YTD] FROM @Data
) AS A
WHERE A.YTD = N'True'

结果:

ENQ-001 True
ENQ-003 True

YTD字段中必须有导致将其作为日期时间类型返回的结果。

尝试查询:

SELECT * FROM dbo.vw_SalesPO_YTD WHERE ISDATE(YTD)= 1

更新的问题: 试试:

ISNULL(CASE WHEN  Award_Date <= DATEFROMPARTS(FinancialYear - 1, 11, 1) + GETDATE() - DATEADD(year, DATEDIFF(month, '20161101', GETDATE()) / 12, '20161101') THEN N'True' ELSE N'False' END, 'false')

答案 3 :(得分:0)

试试这个: - 不要在字符串

之前添加n

SELECT * FROM (SELECT Enquiry_Number, YTD FROM dbo.vw_SalesPO_YTD) AS A WHERE A.YTD = 'True'

答案 4 :(得分:0)

这是一个成功的解决方法,而不是解决方案本身或核心问题的解释。

显然,视图中出现的数据存在问题,不允许在re.IGNORECASE子句中对\w列的结果进行操作,但它们可以按时运行查询到达YTD阶段。

我创建了一个新的WHERE,它明确地将SELECT列定义为table,然后将我视图中的所有记录插入到此表中,该表已解决了该问题。然后可以按照YTD对记录进行排序和过滤。