【问题标题】:SQL Server CTE Implicit Column Datatype issueSQL Server CTE 隐式列数据类型问题
【发布时间】:2012-11-19 15:40:19
【问题描述】:

我在使用 SQL Server 公用表表达式 (CTE) 时遇到了一个非常奇怪的错误。

我认为通过给出代码示例来解释我的问题是最容易的。

CREATE TABLE #Test1 (TestCol varchar(3));

INSERT INTO #Test1 VALUES ('012')
INSERT INTO #Test1 VALUES ('ABC')

--This simple shows the Cast works as expected, and only on rows where the TestCol value is numeric
SELECT TestCol, CAST(TestCol as int) as IntCast 
FROM #Test1 
WHERE ISNUMERIC(TestCol) = 1;

--Here I create a cte using the same SQL as show above.
with cte as (
    SELECT 
       TestCol, CAST(TestCol as int) as IntCast 
    FROM #Test1 
    WHERE ISNUMERIC(TestCol) = 1
)

/*
I have two examples below. The first can be executed to check for the existence of our 'ABC' value.  It doesn't show up, which is expected. 
The Second example, simple checks to see if our IntCast column is greater than 10.  This throws an exception
*/

--SELECT * FROM cte
SELECT * FROM cte WHERE IntCast > 10

DROP TABLE #Test1

这里的例外是

将 varchar 值 'ABC' 转换为数据类型 int 时转换失败

我很好奇这是在哪里发生的?

【问题讨论】:

  • 我猜是CAST(TestCol as int) ?试试不带CAST?
  • 不,它甚至不应该在 CTE 中返回“ABC”。
  • @Jim - 没错。看起来 CTE 改变了事情完成的顺序,因此在应用过滤器之前尝试了强制转换。但是,如果没有 cte,它会起作用。奇怪的行为。
  • 子查询似乎有同样的问题:SELECT * FROM (SELECT CAST(TestCol AS INT) AS IntCol FROM #Test1 WHERE ISNUMERIC(TestCol) = 1 ) AS sub WHERE IntCol > 10

标签: sql-server common-table-expression


【解决方案1】:
with cte as (
    SELECT TestCol, Case when ISNUMERIC(TestCol) = 1 then CAST(TestCol as int) else NULL end as IntCast FROM #Test1  
)

【讨论】:

  • 这解决了我的问题。我很欣赏周围的工作,尽管我对“为什么会发生”比“如何解决它”更感兴趣。我还是接受了你的回答。
  • 对不起,不知道,在我看来优化器似乎走的是一条神秘的全面评估之路……
猜你喜欢
  • 1970-01-01
  • 2018-02-07
  • 2021-05-19
  • 2016-05-22
  • 2011-05-20
  • 1970-01-01
  • 2023-03-13
  • 2017-08-29
相关资源
最近更新 更多