none
类型转换问题 RRS feed

  • 问题

  • 在一个表中,有个 VARCHAR 字段,有部分数据的值是数字,有部分是字符串,我把一部分数据取出来,取出来的部分该字段都是数字,然后我把这部分数据通过 CONVER 转换成 INT,这里没有问题,但当我再用这个 CONVERT 后的值,进行一些比较操作,数据库就会报类型转换异常了

    以下是示例

    WITH tb_testl AS (
    -- 数据表格,有两列,id 列是 INT,value 列是 VARCHAR,其中 value 列有部分数据不能转换为 INT
     SELECT 1 AS id ,'hehe' AS value 
     UNION ALL SELECT 1 AS id, '1' AS value 
     UNION ALL SELECT 2 AS id, '2' AS value 
     UNION ALL SELECT 2 AS id, '2' AS value
    ), tb_test2 AS ( 
    -- 从表 1 中取出部分数据,将 VALUE 列转换为 INT,这里取出来的 value 列都确实可以转换为 INT
     SELECT CONVERT(INT , value) AS value FROM tb_testl WHERE id = 2 
    )
    -- 查询表 2,如果这里不带 WHERE 条件是可以正常查询的,但带上条件后就会报错类型转换异常
    SELECT * FROM tb_test2 WHERE value = 2;

    上面这段 sql 会报类型转换的错误,而如果我把最后一行的WHERE value = 2;这个条件删除的话就不会报错了,个人感觉是数据库先使用了我后面加的这个条件,而没有来得及使用tb_test2中的条件筛选数据导致异常,求教我该怎么解决?
    数据库是 mssql2008

    2018年8月2日 3:47

答案

  • Hi,

    >> 个人感觉是数据库先使用了我后面加的这个条件,而没有来得及使用tb_test2中的条件筛选数据导致异常,求教我该怎么解决?

    并不完全是这样的,事实上使用公用表表达式(CTE)只是在视觉上给人一种先得出了 tb_test2在得出结果的感觉,事实上在执行过程中并不是这个样子的。查看查询计划会发现执行过程和下面这个语句类似:

     WITH tb_test2 AS (
    
     SELECT 1 AS id ,'hahah' AS value 
     UNION ALL SELECT 1 AS id, '1' AS value 
     UNION ALL SELECT 2 AS id, '2' AS value 
     UNION ALL SELECT 2 AS id, '2' AS value
    )
    
     SELECT CONVERT(INT , value) AS value FROM tb_test2 WHERE id = 2 and  [value] = 2 

    在SQL Server内部,真正执行的是

    而如果没有那个where条件,则只执行

    并不存在什么“没有来得及使用tb_test2中的条件筛选数据导致异常”这种说法。用嵌套子查询得出的结果也是一样的,这种情况我们可以使用临时表:

     WITH tb_test2 AS (
    
     SELECT 1 AS id ,'hahhahah' AS value 
     UNION ALL SELECT 1 AS id, '1' AS value 
     UNION ALL SELECT 2 AS id, '2' AS value 
     UNION ALL SELECT 2 AS id, '2' AS value
    )
    
    SELECT CONVERT(INT , value) AS value into #table FROM tb_test2 WHERE id = 2 
    select * from #table where [value] = 2

    Best Regards,

    Teige


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    2018年8月2日 6:50
    版主

全部回复

  • Hi,

    >> 个人感觉是数据库先使用了我后面加的这个条件,而没有来得及使用tb_test2中的条件筛选数据导致异常,求教我该怎么解决?

    并不完全是这样的,事实上使用公用表表达式(CTE)只是在视觉上给人一种先得出了 tb_test2在得出结果的感觉,事实上在执行过程中并不是这个样子的。查看查询计划会发现执行过程和下面这个语句类似:

     WITH tb_test2 AS (
    
     SELECT 1 AS id ,'hahah' AS value 
     UNION ALL SELECT 1 AS id, '1' AS value 
     UNION ALL SELECT 2 AS id, '2' AS value 
     UNION ALL SELECT 2 AS id, '2' AS value
    )
    
     SELECT CONVERT(INT , value) AS value FROM tb_test2 WHERE id = 2 and  [value] = 2 

    在SQL Server内部,真正执行的是

    而如果没有那个where条件,则只执行

    并不存在什么“没有来得及使用tb_test2中的条件筛选数据导致异常”这种说法。用嵌套子查询得出的结果也是一样的,这种情况我们可以使用临时表:

     WITH tb_test2 AS (
    
     SELECT 1 AS id ,'hahhahah' AS value 
     UNION ALL SELECT 1 AS id, '1' AS value 
     UNION ALL SELECT 2 AS id, '2' AS value 
     UNION ALL SELECT 2 AS id, '2' AS value
    )
    
    SELECT CONVERT(INT , value) AS value into #table FROM tb_test2 WHERE id = 2 
    select * from #table where [value] = 2

    Best Regards,

    Teige


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    2018年8月2日 6:50
    版主
  • CTE 并不控制执行顺序,它会被展开并且可能和外部条件合并的

    像这个,你可以改写语句控制一下,比如加上 TOP 10,这样就不会出问题了

    SELECT top(10) CONVERT(INT , value) AS value FROM tb_testl WHERE id = 2
    )

    2018年8月3日 1:02