SQL之恋(4):初识T-SQL,恋情的开始
软件世界
SQL是大多数DBMS(数据库管理系统)对数据库进行各种操作时所使用的语言,而T-SQL(Transact-SQL的简称)则是MS SQL Server对SQL标准的实现,要学习SQL Server,必须熟练掌握T-SQL,现在让我们一起来认识它。
老生常谈 SQL是什么
SQL(Structured Query Language,结构化查询语言)是一个抽象的概念,是由ANSI(American National Standards Institute,美国国家标准局)制定的一套“规范”,目前最新的版本是SQL-99(SQL-3),比较流行的版本是SQL-92(SQL-2)。
现实世界中没有哪一种DBMS能够完全实现所有的SQL标准,各种DBMS只是实现了SQL标准的某些部分;同时,DBMS厂商还会根据各自的情况赋予自己的“SQL语言”不同的特性(美其名曰:扩展或增强),这样SQL世界就有了很多“方言”,其中比较著名的是Oracle支持的PL/SQL和SQL Server支持的Transact-SQL。
初识 T-SQL又是什么
T-SQL语言首先是SQL 语言,所以它实现了SQL 标准所规定的最基本的功能,就是DDL和DML。DDL(Data Definition Language,数据定义语言)主要用来创建和删除数据结构,管理对象级的安全机制;DML(Data Manipulation Language,数据操作语言)主要用来查询、添加、修改、删除数据表中的数据。
SQL标准从一开始就是作为定义和操作数据库的语言出现,并非要作为全能的编程语言。而实践中,需要SQL Server提供比较完整的结构化编程功能,于是T-SQL对SQL标准进行了扩展,加入了程序流程控制结构(如if和while)、局部变量和其他一些功能;另外,由于历史的原因,在一些语法或函数表达上T-SQL 与SQL标准也不尽相同,不过微软正在积极地改变这种情况,使T-SQL更加规范。
提示:我们在学习T-SQL语言时,没有必要刻意关心哪些语句或是关键字是SQL标准,哪些是T-SQL的扩展。事实上,常见的数据库操作(基础的DDL和DML),在绝大多数支持SQL 语言的数据库中是差不多的,所以数据库开发人员在跨越不同的数据库产品时,一般不会遇到什么障碍。但是对于数据库管理员来说,就需要面对很多挑战,因为不同的DBMS在管理、维护和性能调整方面区别很大。
一个忠告 学会忘记
“战壕里的同志”能够给“新兵”的第一个忠告是:学会忘记。这句话有两层意思:一是要忘记原来在大脑中根深蒂固的结构化编程观念;二是如果你使用过基于记录行处理的工具,例如FoxPro中的XBASE语言部分、ADO中的RecordSet、Delphi中的DataSet,那么也请忘掉!
个中原由,且听笔者慢慢道来。
SQL语言是面向“数据集”的语言,通过处理数据集之间的关系或者数据集内部的关系得到用户需要的结果集(也是一个数据集)。什么是数据集呢?笔者以为,逻辑上数据集是一个表或者是表中的一部分,也可以是几个表根据关系连接以后产生的结果;物理上可以把数据集想象成为一个由行和列(字段)组成的二维数据结构。
与面向“数据集”相对的一种处理方式是面向“记录行”,典型的代表就是XBASE语言。这种处理方式的核心是把二维的表(数据集)看成无数独立的记录行:先利用循环语句对数据集进行遍历,把数据集分解为多个记录行,然后用条件判断语句对当前记录行进行处理,最后得到想要的结果。可以肯定,面向记录行与结构化编程是不可分割的。
一个例子 SQL Server VS VFP
我们来看一个例子(见下表),分别用面向数据集的方法和面向记录行的方法实现同样的功能:列出Northwind数据库(SQL Server自带的数据库)中可以销售的产品的信息(包括产品类别、产品名称和单价等)。
提示:上述例子并不是说FoxPro不支持SQL,其实FoxPro早在10多年前就支持SQL了!笔者选用Visual FoxPro是因为XBASE是面向记录行操作的典型代表,而且普及面很广。上表右列的代码在VFP 8下通过,VFP 8附带了Northwind的Fox版本。
这是一个有趣的试验,虽然得到了同样的结果,但是两种“流派”思想方法的不同造成了实现方法的极大差别。先分析比较容易理解的面向记录行的思路:对记录行进行导航(在记录行间前后移动),取得需要的信息,所以在写程序时不可能避免使用循环和条件判断结构;面向数据集的核心思想是数据集之间的关系,这里它根据Categories表和Products表之间的关系(Categories.CategoryID=Products.CateGoryID)把它们连接成为新的数据集,然后根据产品是否可以销售(Discontinued=0)进行过滤,剩下的数据集就是我们需要的结果。
从用户的角度看,采用面向数据集的方法使用的代码很少,写命令就像说话一样,只要以一定的规范告诉数据库你的需求,剩下的都由DBMS处理,用户只须坐等结果就行了;而采用面向记录行的方法使用的代码很多,看上去蛮复杂的,它需要用户事先想好获取结果的方案,然后告诉数据库具体应该如何做,过程比较繁杂。不过,虽然复杂,但这种思路符合一般人的思维方式,较容易被接受。
从上面例子可以看出,面向数据集的SQL语言更加智能化,如果不能理解SQL语言面向数据集的思维方式,仍用面向记录行的思路想问题,永远也写不出有“灵魂”的SQL语句。
有个矛盾
笔者在前文提到过,T-SQL支持循环和判断语句,这不是前后矛盾?实际的工作中,面向数据集的方法并不是万能药,不一定能够摆平所有问题,有些时候还需要面向记录行的方法来帮忙。所以在T-SQL里支持“游标”,辅以循环和条件判断语句,完成类似于XBASE那样的工作。不过要记住一点:在SQL Server里,除非必需,不然的话能不用游标就不用,因为它的效率远远不及SQL语句,而SQL Server是天生的面向数据集者!
T-SQL是一个很庞大的体系,本文旨在给朋友们一个总体的、初步的印象,谈不上“登堂入室”,只能称为“初探”。有兴趣的读者可以查阅相关资料,当然,别忘了本版的“SQL乐园”。根据笔者的经验,认真看书,结合实践,一年左右,当有小成。
