将varchar转换为数值数据类型的算术溢出错误-找不到合适的答案

杰夫·K627

搜寻了一个小时,找不到解决我的代码所发生问题的答案。此查询愉快地返回数据:

WITH RESULTS_TEST_COMPONENT_CTE(RequisitionNumber, ResultsName, ResultValue)
AS
(
SELECT [RequisitionNumber]
      ,[ResultsName]
      ,LTRIM(RTRIM([ResultValue]))
FROM dbo.RESULTS_TEST_COMPONENT
--WHERE TestGroupNumber IN ('T4367', 'T8033')
WHERE SUBSTRING(RequisitionNumber, 2, 4) = '1521'
AND ResultsName = 'HEMOGLOBIN A1C'
AND ISNUMERIC(ResultValue) = 1
)
, RESULTS_TEST_COMPONENT_CTE2(RequisitionNumber, ResultsName, ResultValue)
AS
(
SELECT RequisitionNumber
      ,ResultsName
      ,CAST(ResultValue AS decimal(3,1)) AS ResultValue
FROM RESULTS_TEST_COMPONENT_CTE
)
SELECT * FROM RESULTS_TEST_COMPONENT_CTE2

正如预期的那样,这是数据的前几行:

RequisitionNumber   ResultsName     ResultValue
C1521020510         HEMOGLOBIN A1C  5.9
C1521044250         HEMOGLOBIN A1C  5.4
C1521123010         HEMOGLOBIN A1C  5.6
C1521121420         HEMOGLOBIN A1C  5.8
C1521102210         HEMOGLOBIN A1C  13.2

但是,当我将最后一行更改为此时,它将引发“将varchar转换为数字数据类型的算术溢出错误”。错误:

SELECT * FROM RESULTS_TEST_COMPONENT_CTE2 
WHERE CAST(ResultValue AS decimal(3,1)) BETWEEN 7.5 AND 10

如果我省略“ CAST”并放进去,我也会得到错误WHERE ResultValue BETWEEN 7.5 AND 10我已经确认ResultValue列中的所有数据都是数字,格式为00.0。我需要WHERE子句来满足值> = 7.5和<= 10的要求。我希望它返回最后一行,其中ResultValue为13.2,但是我收到了该错误。谁能告诉我问题是什么?

(如果我仅使用第一个CTE,也会收到错误消息。)

加雷斯

这里有两个问题,第一个是仅仅因为某些事物通过,ISNUMERIC并不意味着您可以将其转换为小数。以下将返回1:

SELECT  ISNUMERIC('1,0');

但这将返回错误:

SELECT CAST('1,0' AS DECIMAL(3, 1))

另一个不太明显的问题是您无法控制SQL Server何时执行哪个操作,因此即使您ISNUMERIC(resultValue) = 1在第一个CTE中进行控制,也无法保证此操作将在之前执行WHERE CAST(ResultValue AS decimal(3,1)) BETWEEN 7.5 AND 10因此,您仍可能会尝试(但失败)将非数字值转换为小数。它在中时有效,SELECT因为它是在之后进行评估的WHERE

有两种解决方法,后一种是hack。解决该问题的最佳方法是通过使用临时表来强制第一个查询的实现:

CREATE TABLE #ResultsComponent
(
    [RequisitionNumber] VARCHAR(50),
    [ResultsName] VARCHAR(50),
    ResultValue DECIMAL(3, 1)
);
INSERT #ResultsComponent (RequisitionNumber, ResultsName, ResultValue)
SELECT [RequisitionNumber]
      ,[ResultsName]
      ,LTRIM(RTRIM([ResultValue]))
FROM dbo.RESULTS_TEST_COMPONENT
--WHERE TestGroupNumber IN ('T4367', 'T8033')
WHERE SUBSTRING(RequisitionNumber, 2, 4) = '1521'
AND ResultsName = 'HEMOGLOBIN A1C'
AND ISNUMERIC(ResultValue) = 1;

SELECT  RequisitionNumber, ResultsName, ResultValue
FROM    #ResultsComponent
WHERE   ResultValue BETWEEN 7.5 AND 10;

另一种方法是hack,不能保证能正常工作,它是TOP用来强制执行顺序的,但是要确保选择的值足够高,以免影响结果:

WITH RESULTS_TEST_COMPONENT_CTE(RequisitionNumber, ResultsName, ResultValue)
AS
(
SELECT TOP (100000)
        [RequisitionNumber]
      ,[ResultsName]
      ,LTRIM(RTRIM([ResultValue]))
FROM dbo.RESULTS_TEST_COMPONENT
--WHERE TestGroupNumber IN ('T4367', 'T8033')
WHERE SUBSTRING(RequisitionNumber, 2, 4) = '1521'
AND ResultsName = 'HEMOGLOBIN A1C'
AND ISNUMERIC(ResultValue) = 1
)
SELECT RequisitionNumber
      ,ResultsName
      ,CAST(ResultValue AS decimal(3,1)) AS ResultValue
FROM RESULTS_TEST_COMPONENT_CTE
WHERE CAST(ResultValue AS decimal(3,1)) BETWEEN 7.5 AND 10;

我们可以很简单地重现问题:

CREATE TABLE #T (ResultValue VARCHAR(100))
INSERT #T (ResultValue)
SELECT  t.ResultValue
FROM    sys.all_objects o
        CROSS APPLY (VALUES (CAST(Name AS VARCHAR(100))), (CAST(object_id AS VARCHAR(100)))) t (ResultValue);

WITH CTE AS
(   SELECT  ResultValue = CAST(ResultValue AS INT)
    FROM    #T
    WHERE   ISNUMERIC(ResultValue) = 1
)
SELECT  *
FROM    CTE 
WHERE   ResultValue BETWEEN 1 AND 10;

然后查看估计的计划(由于错误而无法获得实际计划),并看到两个谓词(ISNUMERICBETWEEN 1 AND 10)同时被评估:

在此处输入图片说明

通过添加top,我们可以更改计划,以便初始表扫描筛选器针对ISNUMERIC,然后使用其他步骤来确保BETWEEN 1 AND 10仅将其应用于数字数据:

WITH CTE AS
(   SELECT  TOP (1000000) ResultValue = CAST(ResultValue AS INT)
    FROM    #T
    WHERE   ISNUMERIC(ResultValue) = 1
)
SELECT  *
FROM    CTE 
WHERE   ResultValue BETWEEN 1 AND 10;

在此处输入图片说明

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

SQL Server:将表达式转换为数据类型bigint的算术溢出错误

来自分类Dev

SQL算术溢出错误将表达式转换为数据类型nvarchar

来自分类Dev

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

来自分类Dev

无法提取响应:找不到合适的HttpMessageConverter作为响应类型

来自分类Dev

算术溢出错误将varchar转换为数值类型的数据?

来自分类Dev

加载XCTest时出错,找不到合适的图像。

来自分类Dev

将IDENTITY转换为数据类型tinyint的算术溢出错误

来自分类Dev

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

来自分类Dev

SQL:左联接和求和:将表达式转换为数据类型int的算术溢出错误

来自分类Dev

**偶尔**算术溢出错误将表达式转换为数据类型int

来自分类Dev

Guice配置错误:找不到合适的构造函数

来自分类Dev

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

来自分类Dev

成功执行后,我收到错误:将表达式转换为数据类型int的算术溢出错误

来自分类Dev

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

来自分类Dev

出现错误时,算术溢出错误将数字转换为数据类型数字

来自分类Dev

SUM(myfield):将数字转换为数据类型数值的算术溢出错误

来自分类Dev

在存储过程中将varchar转换为数值类型的算术溢出错误

来自分类Dev

在Java中找不到合适的驱动程序错误?

来自分类Dev

sql将int转换为datetime,溢出问题将表达式转换为数据类型varchar的算术溢出错误

来自分类Dev

将varchar转换为数值数据类型的算术溢出错误?

来自分类Dev

在执行查询时将数值转换为数据类型数值的算术溢出错误

来自分类Dev

将数据类型从varchar转换为数值时出错

来自分类Dev

SQL:左联接和求和:将表达式转换为数据类型int的算术溢出错误

来自分类Dev

如何解决“找不到合适的驱动程序”错误

来自分类Dev

存储过程算术溢出错误将表达式转换为数据类型int

来自分类Dev

在var.net中将varchar转换为数值类型的算术溢出错误

来自分类Dev

在触发器获取错误中,将数据类型varchar转换为数值时出错

来自分类Dev

JDBC连接MSQL错误“找不到合适的驱动程序”

来自分类Dev

在SQL中将数字转换为数据类型数字的算术溢出错误

Related 相关文章

  1. 1

    SQL Server:将表达式转换为数据类型bigint的算术溢出错误

  2. 2

    SQL算术溢出错误将表达式转换为数据类型nvarchar

  3. 3

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

  4. 4

    无法提取响应:找不到合适的HttpMessageConverter作为响应类型

  5. 5

    算术溢出错误将varchar转换为数值类型的数据?

  6. 6

    加载XCTest时出错,找不到合适的图像。

  7. 7

    将IDENTITY转换为数据类型tinyint的算术溢出错误

  8. 8

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

  9. 9

    SQL:左联接和求和:将表达式转换为数据类型int的算术溢出错误

  10. 10

    **偶尔**算术溢出错误将表达式转换为数据类型int

  11. 11

    Guice配置错误:找不到合适的构造函数

  12. 12

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

  13. 13

    成功执行后,我收到错误:将表达式转换为数据类型int的算术溢出错误

  14. 14

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

  15. 15

    出现错误时,算术溢出错误将数字转换为数据类型数字

  16. 16

    SUM(myfield):将数字转换为数据类型数值的算术溢出错误

  17. 17

    在存储过程中将varchar转换为数值类型的算术溢出错误

  18. 18

    在Java中找不到合适的驱动程序错误?

  19. 19

    sql将int转换为datetime,溢出问题将表达式转换为数据类型varchar的算术溢出错误

  20. 20

    将varchar转换为数值数据类型的算术溢出错误?

  21. 21

    在执行查询时将数值转换为数据类型数值的算术溢出错误

  22. 22

    将数据类型从varchar转换为数值时出错

  23. 23

    SQL:左联接和求和:将表达式转换为数据类型int的算术溢出错误

  24. 24

    如何解决“找不到合适的驱动程序”错误

  25. 25

    存储过程算术溢出错误将表达式转换为数据类型int

  26. 26

    在var.net中将varchar转换为数值类型的算术溢出错误

  27. 27

    在触发器获取错误中,将数据类型varchar转换为数值时出错

  28. 28

    JDBC连接MSQL错误“找不到合适的驱动程序”

  29. 29

    在SQL中将数字转换为数据类型数字的算术溢出错误

热门标签

归档