我确信这必须在某个地方记录下来,但就我而言,我似乎找不到任何解释这种行为的实际文档。
采用4种参考表格的方法(我不相信还有更多,但可以随时更正(:
- 当前数据库
- 远程数据库
- 链接服务器
- 同义词
它们在使用多部分列标识符时的行为似乎有所不同,我正在努力理解其背后的原因。我测试了各种类型的SELECT
语句:
当前数据库
工作
SELECT Column FROM Schema.Table;
SELECT Table.Column FROM Schema.Table;
SELECT Schema.Table.Column FROM Schema.Table;
SELECT Alias.Column FROM Schema.Table AS Alias;
即使这样也行(显然只有在使用dbo-Schema时,但仍然如此(
SELECT Schema.Table.Column FROM Table;
远程数据库
工作
SELECT Column FROM RemoteDB.Schema.Table;
SELECT Table.Column FROM RemoteDB.Schema.Table;
SELECT RemoteDB.Schema.Table.Column FROM RemoteDB.Schema.Table;
SELECT Alias.Column FROM RemoteDB.Schema.Table AS Alias;
失败
SELECT Schema.Table.Column FROM RemoteDB.Schema.Table;
The multi-part identifier "Schema.Table.Column" could not be bound.
链接服务器
工作
SELECT Column FROM LinkedServer.RemoteDB.Schema.Table;
SELECT Table.Column FROM LinkedServer.RemoteDB.Schema.Table;
SELECT Alias.Column FROM LinkedServer.RemoteDB.Schema.Table AS Alias;
失败
SELECT Schema.Table.Column FROM LinkedServer.RemoteDB.Schema.Table;
The multi-part identifier "Schema.Table.Column" could not be bound.
SELECT RemoteDB.Schema.Table.Column FROM LinkedServer.RemoteDB.Schema.Table;
The multi-part identifier "RemoteDB.Schema.Table.Column" could not be bound.
SELECT LinkedServer.RemoteDB.Schema.Table.Column FROM LinkedServer.RemoteDB.Schema.Table;
The multi-part identifier "LinkedServer.RemoteDB.Schema.Table.Column" could not be bound.
**I believe this fails are you're only allowed a maximum of 4 parts in the identifier?**
**Read this somewhere but nothing authoritive. Would appreciate a reference.**
同义词
工作
SELECT Column FROM SynonymName;
SELECT Column FROM SynonymSchema.SynonymName;
SELECT SynonymName.ColumnName FROM SynonymSchema.SynonymName;
SELECT SynonymSchema.SynonymName.Column FROM SynonymSchema.SynonymName;
SELECT Alias.Column FROM SynonymSchema.SynonymName AS Alias;
即使这样也行(显然只有在使用dbo-Schema时,但仍然如此(
SELECT SynonymSchema.SynonymName.Column FROM SynonymName;
- 我试图理解为什么某些多部分标识符在以一种方式使用时有效(例如针对本地数据库的模式(,但在以另一种方式(例如针对远程数据库/链接服务器的模式(使用时失败
- 您是否应该始终使用别名来确保一切正常
如有任何建议,我们将不胜感激,尤其是关于设计背后原因的官方文件以及"一刀切"场景的最佳实践建议(我目前推测这是别名路线(。
最佳实践-对表进行别名,并使用由两部分组成的标识符作为列名-第一部分是表别名,第二部分是列名。
为什么?因为:
-
一旦查询包含联接(或应用(,并且该列名恰好属于多个表,则使用单个部分标识符将中断。
-
对一列使用两部分以上的标识符将迫使您将大部分标识符写两次——一次用于列,一次用于表。若有任何更改(如表移动到不同的模式、链接的服务器名称更改、同义词更改(,您现在必须(至少(在两个位置更改查询。
-
对列使用由两部分组成的标识符意味着您确切地知道该列属于哪个表,即使您添加了联接/应用子句,或者只是将具有相同名称的列添加到查询中的一个现有表中,也根本不需要更改查询。此外,您现在只有一个位置可以确定表的来源。
-
对于注释中的链接,不赞成使用由三部分或四部分组成的列标识符(感谢@larnu(。
最重要的是,列属于表。它们不属于服务器、数据库或模式。
请注意,这个答案中的表可以与视图、表值函数、表变量等互换。