随着 SQL Server 版本的演进,T-SQL(Transact Structure Query Language)变得独立而功能强大,且拥有众多使用者,是解决各种数据问题的主流语言。由于公司内各种数据日益庞大、MS SQL Server 的功能扩增、其产品广泛进入企业各系统,让专门处理数据的 T-SQL 语言变成显学。
在关系数据库中,以集合(set)的方式来处理大量纪录才有效率,使得 SQL 语言无法被程序导向语言如 C#/Java/Visual Basic 等取代。而善用数据是信息系统成功的关键因素之一,伴随大量交易、数据整合、商业智能的结构性需求大增,将令 SQL 更形重要。
虽然讨论 T-SQL 的书很多,但因为 SQL Server 2005 巨幅扩增了功能,且标准化了许多语法,将原来需要透过系统预存程序、DBCC 才能建置、设定或维护的功能,都回归到标准的 T-SQL 语法,并放放宽了语法的自由度,例如:建立系统登入与数据库用户、透过 T-SQL 维护索引、TOP 运算符可以搭配变量或子查询,以及搭配 CTE 使用在 UPDATE、DELETE 语法中、汇总运算搭配 OVER 运算符…等,诸多功能在 SQL Server 2000 是无法以 T-SQL 办到的。
我们需要全面性地重新认识 T-SQL,而在这个时间点,够分量的 T-SQL 书籍大概非 Inside Microsoft SQL Server 2005 : T-SQL Programming 和 Inside Microsoft SQL Server 2005 : T-SQL Querying 二书莫属。书籍的作者群里,以资深的讲师与顾问 Itzik Ben-Gan 为首,包含SQL Server 2005 团队的两位产品经理,分别负责SQL Server 查询引擎以及 Service Broker 的深入介绍,以及其他拥有多年经验的顾问与教师们合作撰写,因此,两本书中有着技术底层的详细解说,也有各项功能的最佳应用实作。
作者群们主要以集合数据处理(set-based query)和程序逻辑(procedural programming)两个面向来区分这两本书。前者重视 SQL DML 语法的逻辑和效率,后者则强化搭配过程控制(如 IF、WHILE、游标等)所建构的服务器端对象,如函数、预存程序、CLR 对象、Service Broker 等。
笔者一直认为技术书籍与联机帮助不同的地方是提供应用场景与阅读的趣味,将技术与实务串起来。因为联机帮助写得像字典,若将信息语言的应用比喻为作文,则一般人很难光靠一本字典学会作文。我们需要看文章来模拟笔触、技法与结构。在学习信息技术时,自然需要实务场景和程序代码范例。而这两本书所提供的 T-SQL 范例大都简短有力,两三行就切中要旨,由范例就可看出作者的功力J。对于 T-SQL 的各面向,作者们提纲挈领深入浅出,不管是凸显语法结构、运算符、适用性、建立服务器对象等,都让有 T-SQL 底子的人能迅速抓住重点。
使用 T-SQL 有如激荡脑力的智力测验,同一个问题让人惊艳的解法层出不穷,需要经验与知识的累积,是技术与艺术的展现。而这两本书读来让人愉悦,有如在读 T-SQL 的秘技,作者整合了不同的技术,混在一起使用。例如,以一般的 SELECT 语法查询;要将多笔纪录的域值组成符号分隔的单一字符串时,会采用类似如下的做法:
DECLARE @c nvarchar(4000)
SET @c=''
SELECT @c=@c + CustomerID +',' FROM Customers
SELECT @c
在上述范例中,会传回 Customers 数据表中,以逗号分隔所有客户编号的单一字符串。但作者在Inside Microsoft SQL Server 2005 : T-SQL Programming 一书中,强调此种作法的不确定性,因为微软并没有明文保证此种连接字符串的方法一定可行。但由于 FOR XML 子句在 2005 版本时,多了 PATH 选项,因此组字符串可以换成如下标准的查询方式:
SELECT CustomerID + ',' AS [text()]
FROM Customers FOR XML PATH('')
书中充满了此种结合不同技术的意想不到之解法,让懂得关键之人妙趣横生,不懂奥妙之人,仍可抄袭应用。
善用 T-SQL 查询语法
是否能善用 SQL Server,指标之一是能否精通 SQL 语法。而熟悉 SQL Server 的关连引擎(Relational Engine)如何评估 SQL 语法,如何建立与优化执行计划是一切的基础。针对此,T-SQL Querying 一书的第一章解释了 SELECT 语法的运作逻辑,二、三两章则详细解释了执行计划的产生、如何观察、以及查询语法的优化。
在随后的第四到第八章中,介绍了子查询、Ranking 函数、Join、汇总、Top、Apply、修改数据等项目,个别针对 SQL 语法中的特殊功能逐一介绍。作者在说明个别的功能时,并非单调地举个简单的例子,说明一下用途和语法就结束了。大多会延伸该功能的设计意涵,或以相同目的但不同解法做个比较,让你明了该项功能的优点,例如在介绍 Ranking 系列函数 Row_Number 时,就比较了欲取回查询结果每笔纪录的循序编号,可用自动编号(Identity)、光标(cursor)、子查询以及系统含数 Row_number 等,除了 Row_number 本身的功能外,其间的效率差异才是重点。
最后一章广泛地介绍如何用 T-SQL 来处理数据结构,如 Graph、Tree、阶层与递归等。这让笔者想起在学校时,用 C 语言探讨数据结构的上课情形,没想到也可以用 SQL 语法来介绍J。书中所举的数据结构是我们一般常遇到的,例如制造业的 BOM(Bill of Materials)表,公司的组织结构与运输的道路配置等。当你大脑清醒且一杯咖啡在手时,可以玩玩该主题。
最后,主要作者 Itzik Ben-Gan 开宗明义便强调:撰写 SQL 语法是逻辑推理的训练,而 T-SQL Querying 一书更以 18 个益智题目作结尾,增加了阅读的趣味。
以 T-SQL 完成商业逻辑
Inside Microsoft SQL Server 2005 : T-SQL Programming 一书在前几章详细解释了一般 SQL 使用上,让人困扰的用法,例如以文字型态描述日期时间时,最好采用 [yy]yymmdd[ hh:mm[:ss][.mmm]] 格式,也就是以 ‘20060110’ 来表示时间最佳。前四个章节探讨了动态组织与执行 SQL 语法、临时表和数据表变量、光标等,大家以 T-SQL 撰写商业逻辑时,常用的技巧,作者详加剖析了较佳的用法。
在其后的章节中,本书分别解释了为何要在服务器端建置检视、函数、预存程序、触发、端点、Service Broker 等对象,以及交易管理和错误处理。两书中都解释了许多关于效能的议题,本书第六章特别强调了用户函数的正面价值在于:提供了安全、弹性以及程序的可维护性外,但它可能损伤效能。而第七章说明了预存程序虽然会因为快取执行计划而提升效能,但若数据分布不平均,造成索引误用,依然损伤效能。因此需要小心搭配整个预存程序的 WITH RECOMPILE 选项,或是 SQL Server 2005 新提供的:单句查询语法搭配 OPTION(RECOMPILE) 选项。
读到 Service Broker 的产品经理 Roger Wolter 所撰写的第十一章时,才能理解由于时程压力,为了赶上市而切割 SQL Server 2005 的部分功能。但因功能尚未完成,导致保留的 T-SQL 语法让人莫测高深,这些情况在本章有了解释。例如 Service Broker 在开启对话时,总要以 BEGIN DIALOG CONVERSATION 语法开始,笔者就一直怀疑是否自己的英文能力太差,为何看不出Conversation 加 Dialog 这个关键词的用途L?原来 Conversation 分为 Dialog 和 Monolog 两种,Dialog 是两边的服务可以互为沟通,Monolog 则是发起端单方面的宣告。但 Monolog 在这个版本还未做出来,而为了下一个版本的兼容性,本版就需要保留使用 Dialog 关键词。
另外,在 Queue 的元数据结构中保留了 priority 字段,但我却找不到如何在发送讯息时,设定优先权,结果也是开发小组来不及做,仅留了元数据的字段结构。现阶段若要分辨讯息的优先级,只能自行根据不同的优先权个别建立队列,自己再将讯息派送到正确的队列,并完成处理。我的另一个疑惑是在建立 Service Broker 的对话时,来源端的 Service 名称可以直接指定 Service 对象名称,但目的端却需要用字符串,读了此书才知道因为未来目的端可能不局限是 SQL Server 所提供的服务,因此以一般的文字符串来描述。
阅读建议
这两本书的目的是为了帮助你熟悉 T-SQL 语言,并透过 T-SQL 撰写 SQL Server 服务器端的对象,例如检视、用户自定义函数、预存程序、触发…等等。因此,在顺序上应先阅读 Inside Microsoft SQL Server 2005 : T-SQL Querying,而后才是 T-SQL Programming。两本书的各章节大都彼此独立,且作者所拟的章节针对性很强,你可以博览后,选择主题切入[1]。
笔者读完二书后,个人的感觉是:若你是程序设计师,仅要写好 T-SQL 语法,但无权到 SQL Server 建立对象,则 T-SQL Querying 是你应读的,T-SQL Programming 也值得你参考。但若是数据库管理师,则两本书都应该精读。虽然作者群尽量从基础入门开始介绍,但针对的是 SQL Server 2005 新增的部分,或是与效能相关的深入课题,而未完整解释基本的语法结构。因此,若未经常使用 T-SQL 语言,不习惯以 T-SQL 为主;来处理数据问题。此二书的内容仍然偏难。话虽如此,辅之以联机帮助多读两遍后,相信可让人功力大进。
相关阅读
除了本书外,Inside Microsoft SQL Server 2005 系列丛书中,当下买得到的尚有Kalen Delaney 所著的 Inside Microsoft SQL Server 2005 : The Storage Engine。笔者在先前的专栏中,已经介绍过了该书,在此也就不多赘述。
另外,在这两本书中,作者们处处标示着可延伸阅读的网络链接,笔者稍举觉得有趣的连结:
l 关于 SQL Server 2005 的批次编译、重新编译、计划快取:http://www.microsoft.com/technet/prodtechnol/sql/2005/recomp.mspx
l 透过 C# 写成的 CLR 预存程序,评估 T-SQL 查询语法所花的成本:
http://msdn2.microsoft.com/en-us/library/ms345130.aspx
[1] 本书的作者习惯在文中强调某个重点在丛书中的某章有描述,或是可以参照哪些技术文件。就笔者个人感觉,第一次概览阅读时,不需要跟着跳跃,否则会迷失原有章节的重点。待遇到相关问题,需要精读该章的技术时,再去串连这些延伸阅读。