代码之家  ›  专栏  ›  技术社区  ›  Tomalak

在这种情况下,SQL Server隐式类型转换是如何工作的?

  •  1
  • Tomalak  · 技术社区  · 14 年前

    当我在SQL Server中尝试这个特殊查询时(假设 UserId 是NVARCHAR字段):

    SELECT * FROM MyUser WHERE UserId = 123456
    

    我得到这个错误:

    Msg 245, Level 16, State 1, Line 1
    Syntax error converting the nvarchar value 'foo' to a column of data type int.
    

    显然有一个价值 'foo' 在我的某处 用户ID 列。

    为什么SQL Server试图将我的整个列转换为整数,而不是做我认为显而易见的事情:将搜索值转换为NVARCHAR?

    3 回复  |  直到 14 年前
        1
  •  3
  •   Remus Rusanu    14 年前

    比较是使用 Data Type Precedence :

    当一个运算符将两个 不同数据类型的表达式, 数据类型优先级规则 指定具有 低优先级转换为 具有更高优先级的数据类型。

    这个 NVARCHAR int (优先权16)。请注意,优先级1表示“最高”。

        2
  •  2
  •   Will Marcouiller    14 年前

    我认为这是因为它不能比较不同类型的两个值。然后,is必须将两个相等比较成员转换为同一类型。在这里, int 我想更喜欢。

    我相信 内景 优先于 nvarchar 类型,因此它必须隐式地尝试转换 女巫 到int值。

    编辑1

    “但是,尝试将我给定的值转换为我正在搜索的字段类型,而不是相反,这难道不明智吗?”

    是的,如果是这样就好了。但我想这是因为在尝试其他类型的比较时,会有太多的转换试图暗示。

    where dateOfBirth = 1976-6-16
    

    where dateOfBirth = N'1976-06-16'
    

    在第一个例子中,用户的意图是什么?是为了验证 dateOfBirth 等于的日期值 1976-06-16 或与整数值比较 1976 - 6 - 16 ,这将导致 1954 ,这可能足够合理,可以将其视为任何给定日期的年份。

    我认为有这样的隐性转换 女巫 datetime ,但要涵盖的内容会很多,因此它们仅限于最常见的可能转换。

        3
  •  1
  •   nvogel    14 年前

    如果知道列是NVARCHAR,为什么要指定整数值?

    不幸的是,与许多SQL实现一样,SQL Server在类型支持方面远远落后于其他语言。类型检查通常只在运行时执行。因此,像您这样的查询不会通过语法检查来突出显示像您在这里遇到的问题。您的查询有错误,因为您不匹配不同的类型,但由于SQL Server没有对其进行vaidate,结果将是不可预测的,具体取决于数据。