c# - ISNULL 与 CASE 返回类型

标签 c# sql tsql

我最近在将 TSQL 中的 CASE 语句更改为 ISNULL 函数时遇到了一个有趣的问题。我正在使用的查询用于获取我工作的网站的一些用户属性和权限。以前查询有许多类似于以下的 CASE 语句:

注意:示例中的a.column1是表中的bit类型。另请注意,[CanDoSomething] 结果列有时在网站中用作字符串。

SELECT
    ...
    CASE
        WHEN a.column1 IS NULL THEN 0
        ELSE a.column1
    END [CanDoSomething]
    ...
FROM
    a

DBA 将这些 CASE 语句替换为 ISNULL 函数:

SELECT
    ...
    ISNULL(a.column1, 0) [CanDoSomething]
    ...
FROM
    a

这似乎是一个很好的更改,但在 C# 中检索数据时却导致了一些意想不到的事情。对于前面的查询,从 C# 中的 DataTable 访问时,[CanDoSomething] 列的值为 10。当我们更改为使用 ISNULL 时,C# 中的值随后更改为 truefalse,当将其视为字符串时,显然不是与 10 相同。

由此引起的错误已经得到解决。我很好奇为什么 ISNULL 返回的值与等效的 CASE 语句不同,我似乎无法在 Google 上找到任何答案。

最佳答案

扩展@dasblinkenlight 的解释:

真正的问题是,根据 the documentation , case 表达式

return the highest precedence type from the set of types in *result_expressions* and the optional *else_result_expression*. For more information, see Data Type Precedence (Transact-SQL).

虽然 isnull()

returns the same type as *check_expression*

在您的例子中,这是一个。您的 case 表达式:

CASE
  WHEN a.column1 IS NULL THEN 0
  ELSE                        a.column1
END

具有返回两种不同数据类型的执行路径,int(字面值 0)和 bit(值柱子)。如果您查看 data type precedence chart上面的链接中,int 的优先级高于 bit,因此 bit 值被转换为 int

那是因为从 bitint 的转换是一个加宽转换。 Sql Server 的 bit 类型本质上是一个 1 位整数值,因此不会丢失任何数据。从 intbit 的转换是一个缩小转换,并且存在数据丢失的可能性(至少在概念上)。

如果 DBA 使用 coalesce(),您就不会遇到此问题而不是 isnull(),这本来是我个人的选择,因为 coalesce() 被定义为返回类似于 case 的类型. 合并()

Returns the data type of expression with the highest data type precedence. If all expressions are nonnullable, the result is typed as nonnullable.

关于c# - ISNULL 与 CASE 返回类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20430420/

相关文章:

C# 执行速度 : equal (==) vs not equal (! =)

c# - 如何模拟/覆盖单元测试的只读字段

c# - "The element is missing.."试图用 <element ref =/> 生成类

sql - 使用 T-sql 获取当月的最后一个星期一

c# - C#中Javascript异常消息

java - 使用 getColumnDisplaySize() 来保持整洁?

mysql - 每行除以两列值相同的行的总和

SQL根据多个字段删除重复行

sql - 如何创建SQL Server函数以返回int?

SQL Server : Arithmetic overflow error converting expression to data type int