为啥 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.* 视为相同?的主要内容,如果未能解决你的问题,请参考以下文章