2012-04-05 44 views
6

这似乎是一个相当明显的问题,但我一直无法想出我想问的问题的合适名词,因此为此提供参考资料已经非常棘手。但答案似乎很明显。SQL Server中用于寻址表的正确语法是什么?

在检查SQL Server的Pluralsight培训材料时,他们建议您始终参考“常规”查询(您可能为基本Web服务编写的内容)以及可能存储过程中的SQL查询中的表,如以下:

[databasename].[dbo].[some_table].[sometimesacolumngoeshere] 

虽然我发现它非常普遍遇到存储的特效等,简单地使用:

my_column or [my_column] 

这里的区别显然是一个提供了一个绝对的“地址”明确,而ot她是隐含的。

你怎么知道什么时候适合使用一个,以及你称之为什么,寻址?

我喜欢总是明确的,如果你需要节省空间和/或使事情更清楚,你可以别名到一个明确的完整的“地址”,是否正确?

回答

6

你是对的。基本上,SQL将尝试在FROM和JOIN部分的所有表中找到要查找“my_column”的字段。但是如果你碰巧在表A和表B中有一个“my_column”,那么你需要通过包含表名来明确地告诉它你正在寻找哪个“my_column”。如果你在那里碰撞了,那么这个链会继续到dbo和databasename。

大多数时候,你会发现,人们不明确叫出表一列是,除非他们加入多个表。

比如我写我的疑问是这样的:

SELECT a.field1, b.field2 
FROM tableA AS a 
INNER JOIN tableB AS b ON a.id = b.a_id 
WHERE a.id = 123 

这里我使用的AS别名表A和tableB的下降到更具可读性a和b。我可以很容易地写我的查询是这样的:

SELECT tableA.field1, tableB.field2 
FROM tableA 
INNER JOIN tableB ON tableA.id = tableB.a_id 
WHERE tableA.id = 123 

或者这样,如果FIELD1和FIELD2是唯一的有表,不过这样会有点混乱,以每个数据块的来源。

SELECT field1, field2 
FROM tableA 
INNER JOIN tableB ON tableA.id = tableB.a_id 
WHERE tableA.id = 123 
+1

我不能不同意这一点。使用表别名肯定有助于减少混乱,并通过单独查看查询来提供必要的提示,以告知哪个表是字段来自哪个表。 +1给你。 – David 2012-04-05 17:15:28

2

SQL Server有四个部分名称:

  • 大多数情况下您可以通过名称来引用一个对象

    SELECT * FROM MyTable 
    
  • 然后,您可以指定对象的所有者或模式:

    SELECT * FROM dbo.MyTable 
    
  • 然后您可以引用该对象所在的数据库:

    SELECT * FROM master.dbo.MyTble 
    
  • 最后,你可以参考不同的服务器上的表

    SELECT * FROM test1.master.dbo.MyTable 
    

它比我能解释的更好的MSDN

+0

你至少应该使用的模式,是有性能差异。 – HLGEM 2012-04-05 17:01:52

+0

嗯,我必须调查。 – Phil 2012-04-05 17:03:38

+1

一个小的区别:http://stackoverflow.com/questions/1112374/sql-server-performance-and-fully-qualified-table-names – Phil 2012-04-05 17:06:36

1

我觉得这是这是主观的问题之一,并且会变成一个偏好问题,但是:

从可读性的角度来看,我认为只有在必要时才会明确表示。通常,SQL语句非常复杂,不需要阅读大量不必要的文本。

我认为

SELECT TOP 1000 [StoreNumber] 
     ,[Address1] 
     ,[Address2] 
     ,[City] 
     ,[St] 
     ,[Zip] 
     ,[ZipSuffix] 
     ,[LocationType] 
     ,[LocationSubType] 
     ,[Corp] 
     ,[Division] 
     ,[ZoneNumber] 
     ,[DistrictNumber] 
     ,[StateNumber] 
    FROM [CommonData].[dbo].[vw_StoreData] 

是很多比

SELECT TOP 1000 [CommonData].[dbo].[vw_StoreData].[StoreNumber] 
     ,[CommonData].[dbo].[vw_StoreData].[[Address1] 
     ,[CommonData].[dbo].[vw_StoreData].[[Address2] 
     ,[CommonData].[dbo].[vw_StoreData].[[City] 
     ,[CommonData].[dbo].[vw_StoreData].[[St] 
     ,[CommonData].[dbo].[vw_StoreData].[[Zip] 
     ,[CommonData].[dbo].[vw_StoreData].[[ZipSuffix] 
     ,[CommonData].[dbo].[vw_StoreData].[[LocationType] 
     ,[CommonData].[dbo].[vw_StoreData].[[LocationSubType] 
     ,[CommonData].[dbo].[vw_StoreData].[[Corp] 
     ,[CommonData].[dbo].[vw_StoreData].[[Division] 
     ,[CommonData].[dbo].[vw_StoreData].[[ZoneNumber] 
     ,[CommonData].[dbo].[vw_StoreData].[[DistrictNumber] 
     ,[CommonData].[dbo].[vw_StoreData].[[StateNumber] 
    FROM [CommonData].[dbo].[vw_StoreData] 

(当你开始连接表,更糟糕的,如果你要加入跨不同数据库中的表更糟糕的可读性。)

我能看到你可能会说,第二个是更具可读性如果你需要知道哪些数据库,架构和表中的特定字段来自通过查看单独的查询。

但在SQL Server中,例如,你可以在设计器中打开该查询,看看它在一个更加友好的图形视图。

恕我直言,我会用完整的语法的唯一时间是必要时,渡台/数据库/模式的界限时,或者如果你有使用相同的字段名称的两个表。

例子:

SELECT TOP 1000 [CommonData].[dbo].[vw_StoreData].[StoreNumber] 
     ,[Address1] 
     ,[Address2] 
     ,[City] 
     ,[St] 
     ,[Zip] 
     ,[ZipSuffix] 
     ,[LocationType] 
     ,[LocationSubType] 
     ,[Corp] 
     ,[Division] 
     ,[ZoneNumber] 
     ,[DistrictNumber] 
     ,[StateNumber] 
    FROM [CommonData].[dbo].[vw_StoreData] 
    Inner Join [CommonData].[dbo].[vw_StorePhones] 
    ON [CommonData].[dbo].[vw_StorePhones].[StoreNumber] = [CommonData].[dbo].[vw_StoreData].[StoreNumber] 

即使在这种情况下,我会使用Table Aliases缩短它,并使其更具可读性。

所有这一切都表示,在现实世界中,这是相当有可能你会发现自己工作的公司,已经决定了标准格式,你需要根据公司的标准进行编码。

+0

非常不同意 – HLGEM 2012-04-05 17:03:34

+0

这就是为什么我说这是主观的和偏好的问题。 ;-) – David 2012-04-05 17:06:07

2

虽然可以对列使用implict名称,但从可维护性角度来看,这是一个糟糕的选择。我从来没有把生产代码放在别的列上,因为当你回去一年后改变这个报告或查询时,你真的不想弄清楚你加入的20张表中的哪一张此外,如果没有指定,数据库将难以找到列,并且在没有引用的情况下,在两个表中列名相同的情况下编写更多错误。使用明确的引用是一个好习惯。

1

对象可以通过一个或多个标识符来引用。

您可以使用一个标识符来引用对象,但如果标识符是模糊的,你必须使用多个标识符唯一地标识对象。

例如,两个表命名TableA在不同的模式现有必须在查询中使用的至少一个两个标识符,schema_one.TableAschema_two.TableA被引用。

有一个MDSN page你可以找到更多关于对象名称和标识符。

关于使用多个标识符作为对象名称,如果您更具体,可以减少查询中的歧义并加快解析查询的速度,因为数据库引擎无需解决模糊性问题,但费用高昂查询的可读性。

我个人的偏好(在最常用的对象)使用schema.Table引用时表和column,如果单表查询中引用,并table.column如果多个表在查询中引用。

2

Pluralsight错了。

由于使用引用的对象在同一数据库中,这里有两个理由不以这种方式完全符合一个完全合格的名称的存储过程的例子:

  • 如果你有一个存储过程引用同一个数据库中的对象,如果您重命名数据库,它将会中断。

  • 如果你开始使用Visual Studio的数据库工具数据库脚本添加到源代码控制,你会得到很多的警告处理

这是一个好主意,了解和利用模式正确

0

在大多数情况下,我总是建议使用完整的地址只是为了安全起见

[databasename].[dbo].[some_table].[sometimesacolumngoeshere] 

但是,只有在拥有多个数据库时才需要这样做。我只遇到过一两个选择数据库的问题,这通常是通过在sql server中选择正确的数据库来解决的。

一旦你真的在一个查询中,并且你给了该表一个缩短的别名,那么确实没有必要包含完整的地址,因为这已经被引用。

E.G

FROM [databasename].[dbo].[some_table].[sometimesacolumngoeshere] SOME 

    SELECT SOME.Name