Transact-SQL FETCH 语句不需要 INTO 子句。如果没有指定返回变量,该行就会作为单行结果集,自动返回给客户。但是,如果过程必须给客户提供行,则使用无游标的 SELECT 语句,更为有效。
在每个 FETCH 之后,@@FETCH_STATUS 函数均被更新。它和 PL/SQL 中使用的 CURSOR_NAME%FOUND 和 CURSOR_NAME%NOTFOUND 变量用法类似。每次成功提取后,
@@FETCH_STATUS 函数值被设为 0。如果该提取要读取游标结尾之外的地方,则返回值 -1。如果游标打开后,请求的行已被从表中删除,则 @@FETCH_STATUS 函数返回 -2。通常,返回值 -2 只在使用 SCROLL 选项声明的游标中出现。每次提取后,必须检查该变量,以保证数据的有效性。 SQL Server 不支持 Oracle 的游标 FOR 循环语法。
在 PL/SQL 和 Transact-SQL 中,用于更新和删除的 CURRENT OF 子句语法和函数是相同的。定位 UPDATE 或 DELETE 用于对指定游标内的当前行进行更新和删除操作。
Transact-SQL CLOSE CURSOR 语句关闭游标,但数据结构仍可用于重新打开游标。PL/SQL CLOSE CURSOR 语句关闭并释放所有的数据结构。
Transact-SQL 需要使用 DEALLOCATE CURSOR 语句,删除游标数据结构。DEALLOCATE CURSOR 语句与 CLOSE CURSOR 的不同之处在于,关闭的游标可以重新打开。DEALLOCATE CURSOR 语句释放所有与游标有关的数据结构,并删除游标的定义。
下面示例给出了,PL/SQL 和 Transact-SQL 中对等的游标语句。
Oracle DECLARE VSSN CHAR(9); VFNAME VARCHAR(12); VLNAME VARCHAR(20); Microsoft SQL Server DECLARE @VSSN CHAR(9), @VFNAME VARCHAR(12), @VLNAME VARCHAR(20) CURSOR CUR1 IS DECLARE curl CURSOR FOR SELECT SSN, FNAME, LNAME SELECT SSN, FNAME, LNAME FROM STUDENT ORDER BY LNAME; FROM STUDENT ORDER BY SSN BEGIN OPEN CUR1 OPEN CUR1; FETCH NEXT FROM CUR1 FETCH CUR1 INTO VSSN, VFNAME, INTO @VSSN, @VFNAME, @VLNAME VLNAME; WHILE (@@FETCH_STATUS <> -1) WHILE (CUR1%FOUND) LOOP BEGIN FETCH CUR1 INTO VSSN, VFNAME, FETCH NEXT FROM CUR1 INTO @VSSN, VLNAME; @VFNAME, @VLNAME END LOOP; END CLOSE CUR1; CLOSE CUR1 END; DEALLOCATE CUR1 优化 SQL 语句
本节提供了用于优化 Transact-SQL 语句的一些 SQL Server 工具的信息。有关优化 SQL Server 数据库的详细信息,请参见本卷前面的“性能优化”。
可以使用 SQL Server 查询分析器的图形显示计划功能,了解优化程序处理语句的详细信息。 此图形工具可以实时地捕获服务器活动的连续记录。SQL Server 事件探查器监视多个不同的服务器事件和事件类别,使用用户定义的标准筛选这些事件,并把跟踪记录输出到屏幕、文件或其它 SQL Server。
SQL Server 事件探查器可用于:
? ? ? ? ? ?
监视 SQL Server 的性能。
调试 Transact-SQL 语句和存储过程。 确定执行缓慢的查询。
解决 SQL Server 中的问题。通过捕获引起某一特定问题的所有事件,然后在测试系统上重现这些事件,以重复和分离该问题,达到解决问题的目的。
在项目开发阶段,通过单步执行语句,每次一行,测试 SQL 语句和存储过程,来确认代码是否按照预期结果执行。
在生产系统上捕获事件,并在测试系统上重现所捕获的那些事件,从而为测试或调试重建了生产环境中所发生的事件。通过在其它系统中重现所捕获的事件,用户可继续使用生产系统,而不会影响正常工作。
SQL Server 事件探查器给一组扩展存储过程提供了图形用户界面。也可以直接使用这些扩展存储过程。因此,可以创建自己的应用程序,它使用 SQL Server 事件探查器扩展存储过程监视 SQL Server。
SET 语句可以为工作会话期、触发器或存储过程运行期设定 SQL Sever 查询处理选项。 SET FORCEPLAN ON 语句强制优化程序按照表在 FROM 子句中出现的顺序处理联接,类似 Oracle 优化程序中使用的 ORDERED 提示。
SET SHOWPLAN_ALL 和 SET SHOWPLAN_TEXT 语句只返回查询或语句的执行计划信息,但不执行查询或语句。要运行查询或语句,将相应的显示计划语句设为 OFF。然后,查询或语句就会执行。SHOWPLAN 选项与 Oracle EXPLAIN PLAN 工具提供的结果类似。
使用 SET STATISTICES PROFILE ON,每个执行的查询返回标准的结果集,然后,返回附加结果集(给出查询执行的事件探查)。其它选项包括 SET STATISTICS IO 和 SET STATISTIECS TIME。 Transact-SQL 语句处理包括分两步,即编译和执行。NOEXEC 选项编译每个查询,但不执行。NOEXEC 设为 ON 时,不执行随后的语句(包括其它 SET 语句),直到 NOEXEC 设为 OFF 为止。 SET SHOWPLAN ON SET NOEXEC ON
go
SELECT * FROM DEPT_ADMIN.DEPT, STUDENT_ADMIN.STUDENT WHERE MAJOR = DEPT go STEP 1
The type of query is SETON STEP 1
The type of query is SETON STEP 1
The type of query is SELECT FROM TABLE DEPT_ADMIN.DEPT Nested iteration Table Scan FROM TABLE
STUDENT_ADMIN.STUDENT Nested iteration Table Scan
Oracle 需要使用提示,来调整基于开销的优化程序的操作和性能。Microsoft SQL Server 基于开销的优化程序不需要使用提示,来协助其查询评估过程。但是在某些情况下,确有使用它们的必要。
INDEX = {index_name | index_id} 提示指定了该表使用的索引名或 ID。 index_id 为 0,就会强制一个表扫描,而当 index_id 为 1,则强制使用聚集索引(如存在)。这和 Oracle 中使用的索引提示类似。
如果其列顺序和 ORDER BY 子句匹配,SQL Server FASTFIRSTROW 提示就会指示优化程序使用非聚集索引。这个提示的运行方式和 Oracle FIRST_ROWS 提示类似。
定义数据库对象
Oracle 数据库对象(表、视图和索引)可以很方便地迁移到 Microsoft SQL Server,因为每种 RDBMS 都严格遵循 SQL-92 标准,该标准是一个关于对象定义的标准。将 Oracle SQL 表、索引和视图定义转换为 SQL Server 表、索引和视图定义,只需要进行相对简单的语法更改即可。下表着重阐述了,Oracle 和 Microsoft SQL Server 数据库对象之间的一些差异。
类别 列数 行大小 Microsoft SQL Server Oracle 1024 254 8060 字节,加 16 字节指向每个 没有限制(但每行只允许一个 long 或 long raw) 最大行数 没有限制 没有限制 每表一个 long 或 和行一起存储的 16 字节指针。long raw。必须在行BLOB 类型存储 数据存储在其它数据页上。 尾。数据存储在与行相同的块上。 每表一个(索引组织的聚集的表索引 每表一个 表) 非聚集的表索引 每表 249 个 没有限制 单索引中索引的16 16 最大列数 索引中列值的最900 字节 1/2 块 大长度 [[[server.]database.]owner.] 表命名规则 [schema.]table_name table_name [[[server.]database.]owner.] 视图命名规则 [schema.]table_name table_name [[[server.]database.]owner.] 索引命名规则 [schema.]table_name table_name 假定您从用来创建数据库对象的 Oracle SQL 脚本或程序入手。只要复制这个脚本或程序,并进行下列修改即可。每个更改均在本节的其它部分进行了讨论。该例取自脚本示例程序脚本 Oratable.sql 和 Sstable.sql。
1. 确保数据库对象标识符符合 Microsoft SQL Server 命名规则。可能只需要更改索引名
称。
2. 修改数据存储参数,使之用于 SQL Server。如果使用 RAID,则不需要存储参数。 3. 修改 Oracle 约束定义,使之用于 SQL。如有必要,则创建触发器,以支持外键 DELETE
CASCADE 语句。如果表跨几个数据库,则使用触发器强制外键关系。 4. 修改 CREATE INDEX 语句,以使用聚集索引。
5. 使用“数据转换服务”,创建新的 CREATE TABLE 语句。检查该语句,注意 Oracle 数
据类型与 SQL Server 数据类型是如何对应的。
6. 删除所有 CREATE SEQUENCE 语句。在 CREATE TABLE 或 ALTER TABLE 语句中,使用标
识符列,替代序列的使用。
7. 如有必要,修改 CREATE VIEW 语句。 8. 删除任何对同义词的引用。
9. 评估 Microsoft SQL Server 临时表的使用,及其在应用程序中的用途。
10. 把 Oracle 的所有 CREATE TABLEUAS SELECT 命令改成 SQL Server 的 SELECTUINTO 语
句。
11. 评估用户定义的规则、数据类型和默认值的潜在用途。
下面图表比较了,Oracle 和 Microsoft SQL Server 处理对象标识符的方式。在大多数情况下,向 SQL Server 迁移时,不需要更改对象名称。
text 或 image 列 Oracle Microsoft SQL Server 1-30 个字符长。 数据库名称:最多 8 个字符长。 1-128 个 Unicode 字符长。 数据库链接名称:最多 128 个字临时表名称:最多 116 个字符长。 符长。 标识符名称可以以字母数字字符或 _ 开头,并且几乎可包含任何字符。 如果标识符以空格开始,并包含除 _、标识符名称必须以字母开头,并包@、# 或 $ 以外的字符,则必须使用 含字母、数字字符或 _、$、和 # 字[](分隔符)将标识符名称括起来。 符。 如果对象开始字符是: @ 它是一个局部变量。 # 它是一个局部临时对象。 ## 它是一个全局临时对象。 表空间名称必须唯一。 数据库名称必须唯一。 在用户帐户(架构)中,标识符名在数据库用户帐户中,标识符名称必称必须是唯一的。 须是唯一的。 在表或视图中,列名必须是唯一在表或视图中,列名必须是唯一的。 的。 在用户架构中,索引名称必须是唯在数据库表名称中,索引名称必须是一的。 唯一的。 当访问 Oracle 用户帐户中的表时,仅按其不合格的名称来选定它。访问其它 Oracle 架构中的表时,在表名称前加上架构名称和一个英文句点 (.)。Oracle 同义词可提供其它的位置透明性。 当 Microsoft SQL Server 引用表时,使用了另一套命名规则。因为 SQL Server 登录帐户可以在多个数据库中使用同一名称创建表,所以可使用下列规则访问表和视图:[[database_name.]owner_name.]table_name
访问以下项中的Oracle 表 用户帐户 SELECT * FROM STUDENT SELECT * FROM STUDENT_ADMIN.STUDENT Microsoft SQL Server SELECT * FROM USER_DB.STUDENT_ ADMIN.STUDENT SELECT * FROM OTHER_DB.STUDENT_ ADMIN.STUDENT 其它架构 以下是命名 Microsoft SQL Server 表和视图的指导原则:
?
使用数据库名和用户名是可选的。当只按名称来引用表时(例如,STUDENT),SQL Server 在当前数据库的当前用户帐户中查找该表。如果没有找到,它就会在该数据库中查找保留用户名 dbo 拥有的相同名称的一个对象。在数据库的用户帐户中,表名称必须唯一。