SQL Prompt根据数据库的对象名称、语法和代码片段自动进行检索,为用户提供合适的代码选择。自动脚本设置使代码简单易读--当开发者不大熟悉脚本时尤其有用。SQL Prompt安装即可使用,能大幅提高编码效率。此外,用户还可根据需要进行自定义,使之以预想的方式工作。
本文探索了表别名的作用,解释了何时需要表别名,并且说明了它们的一般用途,对别名的合理命名的必要性,以及SQL Prompt如何处理它们。
表别名的主要目的(除了需要使用别名的情况之外)是使SQL查询更易于阅读和理解。不,这不是我输入的错误。别名并没有使键入SQL查询变得更加容易和快捷。如果您使用的是SQL Prompt,则尤其如此,因为它会为您完成所有键入操作。
如果启用其“分配别名”选项,则在您输入SQL语句时,SQL Prompt会自动建议一个或两个字符的别名,只是因为它必须提供某些内容但不能提供含义。这样做不是因为简短的无意义的名称更好。这仅意味着数据库开发人员应改进默认别名以提供含义。
在哪里可以使用表别名?
在标准SQL中,仅在SELECT语句中使用别名。 可以说,您只能在具有FROM子句的语句中使用它们,因为SQL Server的语法允许它在UPDATE和DELETE语句中使用FROM子句。 使用表别名时,您只是为表引用的实例提供了特定的名称,而不是实际的表。只有该引用才是别名。
我是否总是需要限定列名?
在SQL中,如果列名本身是模棱两可的,则只需要使用对表源的引用来限定列名,因为列名本身可能来自FROM子句中的一个或多个表源。在SQL Server中,使用合格的列名无论如何都会使解析器更轻松,并使查询更易于阅读。
但是,如果没有JOIN子句,则在列名中添加任何种类的表限定符(无论是否带别名)都是完全多余的,不应使用。
我是否总是需要使用表别名?
要使一列符合其表的资格,通常不必使用表别名(在ANSI SQL中也称为关联名)。您可以只使用提供该列的表源的名称。
仅当引用不具有名称的表源(例如派生表或行集函数)或使用命名表源(例如表,视图或表-)时,才必须使用别名值函数,在同一查询中不止一次。一般而言,如果表源已经有了合适的名称,那么为什么要提供另一个名称呢?通常,您这样做只是为了使查询的意图更加清晰。如果没有,那么它就会成为障碍。
什么时候需要别名?
需要使用别名的原因之一是基表的名称中包含非法字符。您可能看起来很生气,说您永远不会屈服于此,但是另一方面,在表名限定符的开头使用“@”是不合法的,因此表变量是一个问题。例如,如果不为表变量提供别名,则必须提供方括号定界符以通过其全名引用它。当然,如果表中确实包含非法字符,则表别名可以使您免于讨厌的方括号。
您还必须使用表别名来限定一列,而不是依赖于表名(如果该表位于在JOIN中被两次使用的表中)。 例如:
SELECT Object_Schema_Name(TablesEtc.object_id) + '.' + TablesEtc.name AS TableName, Constraints.name + ' (' + RTrim(Constraints.type) + ')' COLLATE DATABASE_DEFAULT AS [Constraint] FROM sys.objects AS TablesEtc INNER JOIN sys.objects AS Constraints ON Constraints.parent_object_id = TablesEtc.object_id WHERE TablesEtc.is_ms_shipped=0 ORDER BY TableName
sys.objects与sys.objects结合在一起,因此如果不使用别名就无法正常工作。 通过为他们选择有意义的名称,我们还可以避免错误。
如果要加入表源(例如查询),则需要提供一个名称。不存在默认名称。在这里,我们将从多行值创建两个表源,然后将它们联接。
SELECT numbers.number, Coalesce(Names.NameForFrequency,'frequently') AS HowManyTimes FROM (VALUES(0),(1),(2),(3),(4),(5)) AS numbers(number) LEFT OUTER join (VALUES(0,'never'),(1,'once'),(2,'twice'),(3,'thrice')) AS Names(number,NameForFrequency) ON numbers.number=Names.number
在第一个示例中,我们使用了AS关键字来表明我们正在引入别名。它是可选的,因此您可以省略它,但这是一个不好的做法,因为它会使您的意图变得不太清楚。
SQL Prompt如何处理别名
启用了“分配别名”选项(“SQL Prompt”>“选项”>“插入的代码”>“别名”)后,SQL Prompt将自动为表源分配别名。但是,它无法猜测SQL背后的故事,因此它不能为您提供有意义的别名,只能提供缩写。除非您提供当前的命名约定作为自定义别名,否则它将尽可能使用表或视图名称的首字母生成别名。如果该初始字符已被使用,它将使用两个字符。
如果您很不幸地被困在“tibbling”约定中(所有表都带有tbl前缀),则可以告诉SQL Prompt忽略它们(通过将它们添加到“Prefixes to ignore”列表中)。 如果名称带有下划线或连字符,或者由两个CamelCase单词组成(例如CustomerAccounts),则在生成两个字母的别名时,SQL Prompt会将其考虑在内。
否则,当在自联接中使用SQL Prompt时,SQL Prompt会为同一表创建其他别名。这是我们之前看到的相同代码,用于获取表的名称及其约束,但带有SQL Prompt的别名建议。它消除了歧义,但是在阅读此版本时,您是否会如此自信,以确保该ON子句正确无误,甚至可以理解您打算提供的内容和方式?
SELECT Object_Schema_Name(O.object_id) + '.' + O.name AS TableName, O2.name + ' (' + RTrim(O2.type) + ')' COLLATE DATABASE_DEFAULT AS [Constraint] FROM sys.objects AS O INNER JOIN sys.objects AS O2 ON O2.parent_object_id = O.object_id WHERE O.is_ms_shipped = 0 ORDER BY TableName;
当SQL Prompt分配别名时,它将在当前查询编辑器窗口中记住该别名,正如您在处理查询并为其添加子句时,从建议框中为您提供的建议中看到的那样。
如果现有代码使用联接并且不使用表别名,则SQL Prompt将使用绿色曲线在表引用下划线,表示违反了其ST010代码分析样式规则。就个人而言,我更喜欢禁用此规则,除非遵循一种样式指南,该指南要求涉及多个表源的每个SELECT都使用别名作为限定符。更直接地,Prompt还强调了违反MI003的不合格列名。
如果添加表别名,然后运行Format SQL命令,它将自动使用别名来限定相关的列名(如果启用了“限定对象名”操作)。
将自定义别名添加到SQL Prompt
您可以根据已建立的命名约定为表或视图指定用户定义的别名。与其他提示选项分开,SQL Prompt当前不支持自定义别名的导入或导出,因此您必须一次键入一个。
要添加用户定义的别名,请在“选项”窗口的“别名”窗口的头部。在“自定义别名”标题下,单击“新建”,然后输入对象的名称及其别名,然后单击“保存”。
即使您可以提供有意义的自定义别名,它们的添加长度也可能足以阻止它们适合“建议”框中建议的“ON表达式”。 在以下屏幕截图中,我使用了一个愚蠢的别名TheTablesAsListedInTheSystemViews,只是为了说明我的意思。 它溢出了建议框。
在这种情况下,一种更简单的解决方案是在查询或例程完成后但保存之前,使用搜索和替换来更改Prompt提供的默认值。
总结
表别名有时是必不可少的,通常对于帮助阐明更复杂的SQL查询的目的很有用。 但是,它们并非始终都是必需的,如果没有JOIN,则在FROM子句中使用它们不会有任何好处。
使用SQL Prompt,我选择更改建议的简短别名,以提供更多解释性的含义。它没有怨恨,而是根据我选择的自定义别名为我提供建议。这将节省大量的单调键入,对此我深表感谢。