? 一个 SQL Server 登录帐户可在多个数据库中拥有名称相同的表。例如,ENDUSER1 帐户拥有下列数据库对象:USER_DB.ENDUSER1.STUDENT 和 OTHER_DB.ENDUSER1.STUDENT。限定符是数据库用户名,而不是 SQL Server 登录名,因为它们并不一定相同。
同时,这些数据库中的其他用户可以拥有相同名称的对象:
? ? ? ?
USER_DB.DBO.STUDENT USER_DB.DEPT_ADMIN.STUDENT USER_DB.STUDENT_ADMIN.STUDENT OTHER_DB.DBO.STUDENT
因此,建议把所有者名称作为数据库对象引用的一部分。如果应用程序有多个数据库,建议把数据库名称也作为引用的一部分。如果查询跨多个服务器,也将服务器名称加到引用中。
?
每个 SQL Server 连接都有一个当前的数据库上下文,它是在登录时使用 USE 语句设定的。例如,假定下列场景:
一个用户,使用 ENDUSER1 帐户,登录到 USER_DB 数据库。用户请求 STUDENT 表。SQL Server 查找 ENDUSER1.STUDENT 表。如果找到该表,则 SQL Server 在
USER_DB.ENDUSER1.STUDENT 上执行请求的数据库操作。如果在 ENDUSER1 数据库帐户中没有找到该表,SQL Server 则在此数据库的 dbo 帐户中查找 USER_DB.DBO.STUDENT。如果该表仍没有找到,SQL Server 就会返回一个错误信息,指出该表不存在。 ? ?
如果另一个用户,例如 DEPT_ADMIN,拥有这个表,表名称前面一定加上数据库用户的名称( DEPT_ADMIN.STUDENT)。否则,数据库名称默认为当前在上下文中的数据库。 如果引用的表在另一个数据库中,该数据库名称必须用作引用的一部分。例如,在 OTHERDB 数据库中,要访问 ENDUSER1 拥有的 STUDENT 表时,就要使用 OTHER_DB.ENDUSER1.STUDENT。
可用两个英文句点将数据库和表的名称分隔开,省略对象的所有者名称。例如,如果应用程序引用 STUDENT_DB..STUDENT,SQL Server 进行如下查询:
1. STUDENT_DB.current_user.STUDENT 2. STUDENT_DB.DBO.STUDENT
如果用户一次只使用一个数据库,在对象的引用中省略数据库名称,这样,在其它数据库中使用该应用程序就变得简单了。所有对象引用隐式访问当前使用的数据库。如果在同一服务器上,要维护一个测试数据库和一个生产数据库,这是很有用的。
因为 Oracle 和 SQL Server 均支持标识 RDBMS 对象的 SQL-92 初级规则,所以,CREATE TABLE 语法是相似的。
Oracle CREATE TABLE [schema.]table_name Microsoft SQL Server CREATE TABLE [server.][database.][owner.] ( table_name {col_name column_properties ( [default_expression] {col_name [constraint [constraint column_properties[constraint [...constraint]]]| [[,] [constraint [...constraint]]]| constraint]} [[,] constraint]} [[,] {next_col_name | [[,] {next_col_name | next_constraint}...] next_constraint}...] ) ) [Oracle Specific Data Storage [ON filegroup_name] Parameters] Oracle 数据库对象名称不区分大小写。在 Microsoft SQL Server 中,取决所选的安装选项,数据库对象名可以是区分大小写的。
SQL Server 第一次安装时,默认的排序次序是字典顺序、不区分大小写。(可以使用 SQL Server 安装程序,设定不同的配置。)因为 Oracle 对象名称始终是唯一的,所以,把数据库对象迁移到 SQL Server,不应有任何问题。建议在 Oracle 和 SQL Server 中所有的表和列名都使用大写,以避免用户在区分大小写的 SQL Server 上安装时出现问题。
有了 Microsoft SQL Server,使用 RAID 通常可简化数据库对象的存放。与 Oracle 索引组织的表一样,SQL Server 聚集索引被集成到表的结构中。
Oracle Microsoft SQL Server CREATE TABLE DEPT_ADMIN.DEPT ( DEPT VARCHAR2(4) NOT NULL, DNAME VARCHAR2(30) NOT NULL, CONSTRAINT DEPT_DEPT_PK PRIMARY KEY (DEPT) USING INDEX TABLESPACE CREATE TABLE USER_DATA USER_DB.DEPT_ADMIN.DEPT ( PCTFREE 0 STORAGE (INITIAL 10K DEPT VARCHAR(4) NOT NULL, NEXT 10K DNAME VARCHAR(30) NOT NULL, MINEXTENTS 1 MAXEXTENTS CONSTRAINT DEPT_DEPT_PK UNLIMITED), PRIMARY KEY CLUSTERED (DEPT), CONSTRAINT DEPT_DNAME_UNIQUE CONSTRAINT DEPT_DNAME_UNIQUE UNIQUE (DNAME) UNIQUE NONCLUSTERED (DNAME) USING INDEX TABLESPACE ) USER_DATA PCTFREE 0 STORAGE (INITIAL 10K NEXT 10K MINEXTENTS 1 MAXEXTENTS UNLIMITED) ) PCTFREE 10 PCTUSED 40 TABLESPACE USER_DATA STORAGE (INITIAL 10K NEXT 10K MINEXTENTS 1 MAXEXTENTS UNLIMITED FREELISTS 1) 在 Oracle 中,可以使用任何有效的 SELECT 命令,来创建表。Microsoft SQL Server 可提供相同的功能,但语法不同。
Oracle Microsoft SQL Server CREATE TABLE STUDENTBACKUP AS SELECT * INTO STUDENTBACKUP SELECT * FROM STUDENT FROM STUDENT 除非要应用的数据库已将 select into/bulkcopy 数据库配置选项设为 ture,否则,SELECTUINTO 不会生效。(数据库所有者可以使用 SQL Server Enterprise Manager 或 Transact-SQL sp_dboption 系统存储过程设定该选项。)使用 sp_helpdb 系统存储过程检查数据库的状态。如果 select into/bulkcopy 没有设为 true,仍可使用 SELECT 语句,将数据复制到一个临时表中。
SELECT * INTO #student_backup FROM user_db.student_admin.student
当使用 SELECT..INTO 语句创建新表时,引用完整性定义并没有被转移到新表中。
必须把 select into/bulkcopy 选项设为 true,这一需求可能使迁移过程变得复杂。如果必须使用 SELECT 语句把数据复制到表中,先创建表,然后使用 INSERT INTOUSELECT 语句加载表。Oracle 和 SQL Server 的语法是一致的,并且不需要设定任何数据库选项。 在 Microsoft SQL Server 中,用于创建视图的语法与 Oracle 相似。
Oracle Microsoft SQL Server CREATE [OR REPLACE] [FORCE | NOFORCE] VIEW [schema.]view_name CREATE VIEW [owner.]view_name [(column_name [, [(column_name [, column_name]...)] column_name]...)] [WITH ENCRYPTION] AS select_statement AS select_statement [WITH CHECK [WITH CHECK OPTION [CONSTRAINT OPTION] name]] [WITH READ ONLY] SQL Server 的视图要求该表存在,并且视图所有者有权访问 SELECT 语句中所指定的表(与 Oracle FORCE 选项类似)。
默认情况下,并不检查视图上的数据修改语句,来确定受影响的行是否在视图的作用域内。要检查所有的修改,则使用 WITH CHECK OPTION。WITH CHECK OPTION 的主要差异在于,Oracle 将其定义为一个约束,而 SQL Server 没有。其它方面,两者是相同的。
定义视图时,Oracle 提供了 WITH READ ONLY 选项。通过将 SELECT 权限仅授予视图用户,SQL Server 应用程序也可获得相同的结果。
SQL Server 和 Oracle 视图均支持使用数学表达式、函数和常量表达式创建派生列。一些 SQL Server 特定的差异有:
? ? ? ?
如果数据修改语句只影响一个基表,则可在多个视图上允许使用数据修改语句(INSERT 或 UPDATE)。在一个语句中,数据修改语句不能用于多于一个表。 视图中的 text 或 image 列不能使用 READTEXT 或 WRITETEXT。 不能使用 ORDER BY、COMPUTE、FOR BROWSE 或 COMPUTE BY 子句。 视图中不能使用 INTO 关键字。
当一个视图是由外部联接定义的,并使用该联接内表一个列上的限定条件进行查询时,SQL Server 和 Oracle 给出的结果可能不同。在大多数情况下,Oracle 视图可以方便地转成 SQL Server 视图。
Oracle CREATE VIEW STUDENT_ADMIN.STUDENT_GPA (SSN, GPA) AS SELECT SSN, ROUND(AVG(DECODE(grade ,'A', 4 ,'A+', 4.3 ,'A-', 3.7 ,'B', 3 ,'B+', 3.3 ,'B-', 2.7 ,'C', 2 ,'C+', 2.3 ,'C-', 1.7 ,'D', 1 ,'D+', 1.3 ,'D-', 0.7 ,0)),2) FROM STUDENT_ADMIN.GRADE GROUP BY SSN Microsoft SQL Server CREATE VIEW STUDENT_ADMIN.STUDENT_GPA (SSN, GPA) AS SELECT SSN, ROUND(AVG(CASE grade WHEN 'A' THEN 4 WHEN 'A+' THEN 4.3 WHEN 'A-' THEN 3.7 WHEN 'B' THEN 3 WHEN 'B+' THEN 3.3 WHEN 'B-' THEN 2.7 WHEN 'C' THEN 2 WHEN 'C+' THEN 2.3 WHEN 'C-' THEN 1.7 WHEN 'D' THEN 1 WHEN 'D+' THEN 1.3 WHEN 'D-' THEN 0.7 ELSE 0 END),2) FROM STUDENT_ADMIN.GRADE GROUP BY SSN Microsoft SQL Server 提供聚集和非聚集的索引结构。这些索引由页组成,页又构成称为“B 树”的分支结构(类似于 Oracle B 树索引结构)。起始页(根级)指定了表中值的范围。根级
页的每个范围都指向另一页(决定节点),它包含的表值范围更窄。依次,这些决定节点可以指向其它决定节点,进一步缩小搜索范围。分支结构的最终级别称为叶级。
聚集索引
在 Oracle 中,聚集索引实现为用索引组织的表。聚集索引与表物理地结合在一起。表和索引共享同一存储区域。聚集索引按照索引的顺序物理地重排数据行,构成中间决定节点。索引的叶级页包含实际的表数据。这种结构只允许每个表一个聚集索引。一旦在表上施加了 PRIMARY KEY 或 UNIQUE 约束,Microsoft SQL Server 就会自动为该表创建一个聚集索引。聚集索引用于:
? ? ?
主键
未被更新的列
使用 BETWEEN、>、>=、< 和 <= 之类的运算符,返回一个值的范围的查询,例如: SELECT * FROM STUDENT WHERE GRAD_DATE BETWEEN '1/1/97' AND '12/31/97' ?
返回大结果集的查询:
SELECT * FROM STUDENT WHERE LNAME = 'SMITH' ?
在排序操作(ORDER BY、GROUP BY)中使用的列。
例如,在 STUDENT 表上,主键 ssn 上加入一个非聚集索引可能是很有帮助的,在 lname、fname(姓、名)上可以创建聚集索引,因为这是将学生分组的常用方法。 ?
将一个表上的活动进行分布,以防止出现“热点”。热点通常是由于多个用户使用升序键对一个表插入造成的。这种应用场景通常用行级锁定来处理。
在 SQL Server 中,删除和重新创建聚集索引是重组表的一种常用技巧。使用这种方法,可以很容易地保证,在磁盘上页是连续的,且可以在表上方便地重建一些可用空间。这与 Oracle 中的导出、删除和导入表类似。
SQL Server 聚集索引和 Oracle 聚集没有任何相同之处。Oracle 聚集是两个或多个表的物理组合,这些表共享相同的数据块,并使用公共列作为聚集键。在 SQL Server 中,没有与 Oracle 聚集相似的结构。
原则上,在表上定义聚集索引可改善 SQL Server 性能和空间管理。如果不了解给定表的查询或更新模式,可在主键上创建聚集索引。
下表给出了,摘自示例应用程序源代码。请注意 SQL Server 聚集索引的使用。
Oracle CREATE TABLE Microsoft SQL Server CREATE TABLE STUDENT_ADMIN.GRADE (