代码之家  ›  专栏  ›  技术社区  ›  Alex from Jitbit

某个特定服务器上的“列名不明确”错误

  •  7
  • Alex from Jitbit  · 技术社区  · 14 年前

    此简单查询引发“含糊不清的列名taskid”错误 仅在一个数据库服务器上 . 这太荒谬了。我们在不同的服务器和不同版本的SQL Server(2005/2008)上使用相同的数据库结构对此进行了测试,只有这个特定客户机的服务器才会抛出错误。我真的很沮丧。

    SELECT Tasks.TaskID
    FROM Tasks
    INNER JOIN TaskHelpers ON TaskHelpers.TaskID = Tasks.TaskID
    ORDER BY TaskID
    

    是的,我知道我可以 Tasks.TaskID 进入 order by 但由于某些原因我不能。

    6 回复  |  直到 7 年前
        1
  •  11
  •   Ray    14 年前

    如果在SQL Server 2000上或在兼容级别80或更低的级别下运行查询,将出现不明确的列名错误。在兼容级别为90或更高的SQL Server 2005/2008上,yur查询运行良好。

    从ORDER BY子句文档中:

    “在SQL Server 2005中,限定的列名和别名解析为FROM子句中列出的列。如果“排序依据”表达式不合格,则该值在select语句中列出的所有列中必须是唯一的。”

        2
  •  8
  •   KM.    14 年前

    我妈妈说 总是用表名/别名限定查询中的每一列 就像“总是在插入中包含所有列名”和“不选择*”等突出显示一样。

    除了让它更容易,因为它是自记录源代码,如果您曾经添加/更改列,则可以防止此错误。

    检查您的兼容性级别,它们与order by的工作方式有区别!

    通常,在兼容级别90及更高级别(SQL Server 2008的默认级别)中,没有表名/别名语句的ORDER BY会产生错误。

    ALTER DATABASE Compatibility Level (Transact-SQL) 请参见:兼容级别80和级别90之间的差异

    兼容级别设置为80

    在中绑定列引用时 按列表到列的顺序 在“选择列表”列中定义 歧义被忽略,列 前缀有时会被忽略。这个 会导致结果集返回 意外的命令。

    例如,ORDER BY子句 单两部分柱 (.)使用 作为对select中列的引用 接受列表,但表别名 被忽略。考虑以下内容 查询。

    从t_表中选择c1=-c1作为x 按X.C1订购

    执行时,列前缀为 按顺序忽略。那种 在上未发生操作 指定的源列(x.c1)为 应为;而发生在 在中定义的派生c1列 查询。执行计划 查询显示 首先计算派生列,然后 然后对计算值进行排序。

    兼容级别设置为90

    列不明确时出现错误。 中指定的列前缀(如果有) 绑定时不忽略排序依据 到选择列表中定义的列。

    考虑下面的查询。

    从t_表中选择c1=-c1作为x order by x.c1。

    执行时,列前缀 ORDER BY子句不被忽略。那种 在指定的源上发生操作 列(x.c1)如预期。执行 此查询的计划显示 操作员命令从T_表返回的行 然后是派生列的值 计算选择列表中定义的C1。

        3
  •  5
  •   Guffa    10 年前

    您可以指定要排序的列的索引:

    SELECT Tasks.TaskID
    FROM Tasks
    INNER JOIN TaskHelpers ON TaskHelpers.TaskID = Tasks.TaskID
    order by 1
    
        4
  •  4
  •   Alex from Jitbit    14 年前

    真的。数据库兼容模式有问题。它被设置为“80”(SQL 2000)。我已将其设置为90,现在查询工作正常。

    有关兼容级别的详细信息,请参见: http://msdn.microsoft.com/en-US/library/ms178653(SQL.90).aspx

        5
  •  1
  •   Rob    14 年前

    如果您尝试使用标识符呢?通过使用这些标识符,SQL Server知道要按哪个列排序。我从来没有用过别的方法,也从来没有遇到过任何问题。我不明白为什么SQL需要这些标识符,很明显,当有不明确的列名时,他不知道从哪里排序。尝试类似的东西;

    SELECT t.TaskID
    FROM Tasks t
    INNER JOIN TaskHelpers th ON th.TaskID = t.TaskID
    order by t.TaskID
    

    编辑: 你为什么不能呢?SQL是否引发错误?

        6
  •  0
  •   Randy Minder    14 年前

    你不能的意思是什么?很明显,任务和任务助手都有一个名为taskid的列。您需要指出排序依据中的列与哪个表相关联。