过滤无效记录后,在带有 WHERE 子句的 SUBQUERY 中将 NVARCHAR 转换为 BIGINT 时出错

Bra*_*rad 3 sql-server subquery cast

我有一个表,其中的 NVARCHAR 列包含无法转换为 BIGINT 的数据。我很清楚这一点,并已使用 过滤掉它ISNUMERIC(BB.NVARCHARCOL) = 1。尽管如此,在尝试查询数据时我仍然收到错误,说明Error converting data type nvarchar to bigint.

以下工作正常(SQL 没有报告错误):

SELECT *
FROM myNormalTable AA INNER JOIN myBadTable BB ON BB.NVARCHARCOL = AA.MYBIGINTCOL
WHERE ISNUMERIC(BB.NVARCHARCOL) = 1
Run Code Online (Sandbox Code Playgroud)

以下抛出错误:

SELECT *
FROM (
    SELECT *
    FROM myNormalTable AA INNER JOIN myBadTable BB ON BB.NVARCHARCOL = AA.MYBIGINTCOL
    WHERE ISNUMERIC(BB.NVARCHARCOL) = 1
    ) ZZ 
WHERE ZZ.MYBIGINTCOL = 1234
Run Code Online (Sandbox Code Playgroud)

这种变化也会引发错误:

SELECT *
FROM (
    SELECT *
    FROM myNormalTable AA INNER JOIN
        (SELECT CAST(NVARCHARCOL AS BIGINT) NVARCHARCOL FROM myBadTable WHERE ISNUMERIC(NVARCHARCOL) = 1) BB
      ON BB.NVARCHARCOL = AA.MYBIGINTCOL
    ) ZZ 
WHERE ZZ.MYBIGINTCOL = 1234
Run Code Online (Sandbox Code Playgroud)

请记住,这不会出错并成功返回所有记录...

SELECT CAST(NVARCHARCOL AS BIGINT) NVARCHARCOL FROM myBadTable WHERE ISNUMERIC(NVARCHARCOL) = 1
Run Code Online (Sandbox Code Playgroud)

我找到了一个解决方案,即在子查询中将 BIGINT 转换为 NVARCHAR:

SELECT *
FROM (
    SELECT *
    FROM myNormalTable AA INNER JOIN myBadTable BB ON BB.NVARCHARCOL = CAST(AA.MYBIGINTCOL AS NVARCHAR)
    WHERE ISNUMERIC(BB.NVARCHARCOL) = 1
    ) ZZ 
WHERE ZZ.MYBIGINTCOL = 1234
Run Code Online (Sandbox Code Playgroud)

如果我将记录插入临时表:

SELECT CAST(NVARCHARCOL AS BIGINT) NVARCHARCOL INTO #TEMP FROM myBadTable WHERE ISNUMERIC(NVARCHARCOL) = 1
Run Code Online (Sandbox Code Playgroud)

我可以在子查询中成功使用该临时表:

SELECT *
FROM (
    SELECT *
    FROM myNormalTable AA INNER JOIN #TEMP BB ON BB.NVARCHARCOL = AA.MYBIGINTCOL
    WHERE ISNUMERIC(BB.NVARCHARCOL) = 1
    ) ZZ 
WHERE ZZ.MYBIGINTCOL = 1234
Run Code Online (Sandbox Code Playgroud)

世界上到底发生了什么事?看起来 SQL 拒绝在运行外部查询之前使用子查询来获取较小的结果集,无论我做什么,它都想使用整个表。SQL Server 2012 开发者版

Sql*_*Zim 5

try_cast()代替使用。

select *
from (
  select *
  from myNormalTable AA
  inner join #TEMP BB on try_cast(BB.NVARCHARCOL as bigint) = AA.MYBIGINTCOL
  --where try_cast(BB.NVARCHARCOL as bigint) is not null /* not neccessary for inner join */
 ) ZZ
where ZZ.MYBIGINTCOL = 1234
Run Code Online (Sandbox Code Playgroud)

在 Sql Server 2012 及更高版本中:当转换失败时,这些都将返回,null而不是错误。


归档时间:

查看次数:

36867 次

最近记录:

9 年,1 月 前