为啥 SQL Server 2000 将 SELECT test.* 和 SELECT t.est.* 视为相同?

Posted

技术标签:

【中文标题】为啥 SQL Server 2000 将 SELECT test.* 和 SELECT t.est.* 视为相同?【英文标题】:Why does SQL Server 2000 treat SELECT test.* and SELECT t.est.* the same?为什么 SQL Server 2000 将 SELECT test.* 和 SELECT t.est.* 视为相同? 【发布时间】:2011-02-27 19:52:42 【问题描述】:

我在 SQL Server 2000 中进行了一个查询,并在表名中间添加了一个句点:

SELECT t.est.* FROM test

代替:

SELECT test.* FROM test

查询仍然完美执行。即使SELECT t.e.st.* FROM test 执行也没有问题。

我在 SQL Server 2008 中尝试了相同的查询,但查询失败(错误:列前缀与查询中使用的表名或别名不匹配)。出于纯粹的好奇,我一直试图弄清楚 SQL Server 2000 是如何处理表名的,这种方式可以让粗略的查询运行,但到目前为止我还没有多少运气。

任何 sql 专家都知道为什么 SQL Server 2000 运行查询没有问题吗?

更新:无论使用何种界面(例如企业管理器、SSMS、OSQL),查询似乎都能正常工作,正如Jhonny 在下面指出的那样,它甚至在您尝试时也能正常工作:

SELECT TOP 1000 dbota.ble.* FROM dbo.table

【问题讨论】:

如果我不得不冒险猜测是因为 SQL 将您的查询作为建议。为了确保以最有效的方式返回结果,它会查看您的查询并对其进行更改以使其更好地工作。在您的示例中,别名并不重要,因为它是 *​​ FROM 表......虽然我无法证明这一点(因此评论而不是回答)您可以尝试进行连接,以便您有 2 个表并像那样测试它吗?如果有可能产生歧义,它可能会开始更加关心。 你现在也让我好奇了!我手头没有 SQL Server 2000 实例,但我很感兴趣... @Shaded,我认为您可能已经找到了解决方案,但即使查询中存在多个表,它似乎也可以工作。此查询也可以正常工作:SELECT t.est.*, t.est2.* FROM test, test2。我还尝试在内部加入几个表以确保运行良好。 我发现了一个中断的情况 - 如果您合法地拥有一个具有给定名称的对象(例如名为 t.est 的表),请在您的查询中引用它,但为它取别名,您现在得到预期的“无效的对象名称” Even SELECT TOP 1000 dbota.ble.* FROM dbo.table 工作,UFF 令人惊叹 【参考方案1】:

SQL Server 2005 及更高版本具有“正确”的架构实现。 SQL 2000 和更早版本没有。细节让我无法理解(自从我使用 SQL 2000 以来已经有好几年了),我清楚地记得你会疯狂地创建任何不属于“dbo”的东西。这一切都与用户和对象所有权有关,但 2000 年及更早的模型相当混乱。希望有人会阅读 BOL,做一些实验,然后在这里发布他们的结果。

【讨论】:

+1。毫无疑问,包括我自己在内的许多人都持有这种观点。【参考方案2】:

也许表名是由前缀和基名的简单连接构成的。

't' + 'est' == 'test'

也许在更高版本的 SQL Server 中,这种区别更加语义化/更加严格。

 owner = t, table = est  !=  table = test 

【讨论】:

我怀疑你已经找到答案了。如果我们能找到任何支持 MS 的文档,我想我们可以就此结案。【参考方案3】:

是在 SSMS 的“打开表”视图中还是通过企业管理器或通过 SSMS 查询窗口?

There is/was a SQL Server 2005 issue with SSMS 所以你运行查询的方式会影响它的行为。

【讨论】:

无论我使用哪个界面,它似乎都能正常工作。到目前为止,我已经测试了 OSQL、Enterprise Manager 和 SSMS 2008 Query Window。【参考方案4】:

S-SQL reference manual:

"[dot] 可用于将多个名称组合成 AB 形式的名称,以引用表中的列,或模式中的表。请注意,您也可以只使用其中带有点的符号。”

所以我认为,如果您将 tblTest 引用为 tblT.est,只要 tblTest 中没有名为“est”的列,它就可以正常工作。

如果找不到用点引用的列名,我想它会检查对象的父级。

【讨论】:

【参考方案5】:

这是一个错误。

leaked out 与 SQL Server 2000 中列名的内部表示有关。

您也将无法创建名称与表+列连接与另一列冲突的表列,例如,如果您有表 User 和 UserDetail,您将无法在这些表中包含列 DetailAge 和 Age表。

【讨论】:

【参考方案6】:

我发现它是一个错误的参考

注意:作为比较的结果 SQL Server 2000 中的算法错误,点 符号本身对 匹配,因此“dbo.t”将成功 与表“dbot”、“d.b.o.t”匹配, 等等

来自http://blogs.msdn.com/b/ialonso/archive/2007/12/21/msg-1013-the-object-s-and-s-in-the-from-clause-have-the-same-exposed-names-use-correlation-names-to-distinguish-them.aspx

已在 SQL Server 2005 中修复。相同链接 > SQL Server 2005 中引入的更改

    与点相关的比较错误已修复。

【讨论】:

以上是关于为啥 SQL Server 2000 将 SELECT test.* 和 SELECT t.est.* 视为相同?的主要内容,如果未能解决你的问题,请参考以下文章

sql server 中 like 中文不匹配问题

sql server2000如何将数字转换为日期时间

如何将 xlsx 文件导入 Sql server 2000

将DBF数据表导入到sql server2000中的问题

将查询从 SQL Server 转换为 Access 2000

sql server 2000 单用户如何设置?