欲了解详细信息,请参看SQL Server联机手册。
分布事务
如果修改两个或者更多的数据库节点上的表,Oracle就自动初始化一个分布式事务。SQL Server分布式事务使用包含在SQL Server中的微软分布事务协调器(Microsoft Distributed Transaction Coordinator,MS DTC)中的两步提交服务(two-phase commit services)。
缺省情况下,SQL Server必须被通知参与分布事务。SQL Server参与一个MS DTC事务可以用下面方式中的任一种来存储:
- BEGIN DISTRIBUTED TRANSACTION语句。该语句开始一个新的MS DTC事务。
- 一个客户端应用程序直接调用DTC事务接口。
在下例中,注意对本地表GRADE和远程表CLASS的分布式更新(使用一个class_name过程):
BEGIN DISTRIBUTED TRANSACTION
UPDATE STUDENT_ADMIN.GRADE
SET GRADE = ''''B+'''' WHERE SSN = ''''111111111'''' AND CCODE = ''''1234''''
DECLARE @retvalue1 int
EXECUTE @retvalue1 = CLASS_SVR1.dept_db.dept_admin.class_name ''''1234'''', ''''Basketweaving''''
COMMIT TRANSACTION
GO
如果程序不能完成事务,则通过ROLLBACK TRANSACTION语句终止该事务。如果程序失败或者参与的资源管理器失败,MS DTC终止该事务。MS DTC不支持分布式的存储点或者是SAVE TRANSACTION语句。如果一个MS DTC事务失败或者后滚,则整个事务退回到分布式事务的起点,而不理会任何存储点。
两步提交处理
Oracle和MS DTC两步提交机制在操作上是相似的。在SQL Server两步提交的第一步,事务管理器请求每一个参与的资源管理器准备提交。如果有任何资源管理器没有准备好,事务管理器就向与事务相关的所有成员广播一个异常中断决定。
如果所有的资源管理器都能成功的准备,事务管理器就广播一个提交决定。这是提交处理的第二步。当一个资源管理器准备好后,事务究竟是提交了还是失败了,这一点还是拿不准。MS DTC维持了一个连续的日志,因此它的提交或者中断决定都是持久的。如果某个资源管理器或者事务管理器失败了,则当它们重新连接上的时候,就能在那个拿不准的事务上协调了。
SQL语言支持
本部分简要介绍了Transact-SQL和PL/SQL语言语法上的相似和不同之处,并且给出了转换策略。
SELECT和数据操作声明
当你把Oracle DML语句和PL/SQL程序移植到SQL Server上时,请按下列步骤进行:
- 检查所有SELECT、INSERT、UPDATE、和DELETE语句是否有效。做任何需要的修改。
- 把所有的外部节点改为SQL-92外部节点语法
- 用适当的SQL Server函数代替Oracle函数
- 检查所有的比较操作符
- 用“+”代替“||”做字符串串联操作符。
- 用Transact-SQL程序代替PL/SQL程序
- 把所有的PL/SQL游标改为无游标SELECT语句或者Transact-SQL游标。
- 用Transact-SQL过程代替PL/SQL过程、函数和封装。
- 把PL/SQL触发器转换为Transact-SQL触发器。
- 使用SET SHOWPLAN语句来调试你的查询以获得高的性能。
SELECT statements语句
Oracle和Microsoft SQL Server用的SELECT语句的语法是类似的。
Oracle
Microsoft SQL
SELECT [/*+ optimizer_hints*/] [ALL | DISTINCT] select_list [FROM {table_name | view_name | select_statement}] [WHERE clause] [GROUP BY group_by_expression] [HAVING search_condition] [START WITH … CONNECT BY] [{UNION | UNION ALL | INTERSECT | MINUS} SELECT …] [ORDER BY clause] [FOR UPDATE]
SELECT select_list [INTO new_table_] FROM table_source [WHERE search_condition] [ GROUP BY [ALL] group_by_expression [,…n] [ WITH { CUBE | ROLLUP } ] [HAVING search_condition] [ORDER BY order_expression [ASC | DESC] ]
In addition:
UNION Operator COMPUTE Clause FOR BROWSE Clause OPTION Clause
SQL Server不支持面向Oracle的基于开销的优化器暗示,必须把这些暗示清除掉。建议使用SQL Server的基于开销的优化器。欲了解详细信息,请参阅本章后面的“调试SQL语句”部分。
SQL Server不支持Oracle的START WITH…CONNECT BY子句。在SQL Server中,你可以用创建一个执行同样任务的存储过程来代替。
SQL Server不支持Oracle的INTERSECT和MINUS集合。SQL Server的EXISTS和NOT EXISTS子句可以完成同样的任务。
下面的例子使用INTERSECT操作符来为所有有学生的班级找到课程代码和课程名称。注意EXISTS操作符是怎样代替INTERSECT操作符的。两者返回的数据是一样的。
Oracle
Microsoft SQL
SELECT CCODE, CNAME FROM DEPT_ADMIN.CLASS INTERSECT SELECT C.CCODE, C.CNAME FROM STUDENT_ADMIN.GRADE G, DEPT_ADMIN.CLASS C WHERE C.CCODE = G.CCODE
SELECT CCODE, CNAME FROM DEPT_ADMIN.CLASS C WHERE EXISTS (SELECT ''''X'''' FROM STUDENT_ADMIN.GRADE G WHERE C.CCODE = G.CCODE)
下例使用MINUS操作符来找出那些没有学生的班级。
Oracle
Microsoft SQL
SELECT CCODE, CNAME FROM DEPT_ADMIN.CLASS MINUS SELECT C.CCODE, C.CNAME FROM STUDENT_ADMIN.GRADE G, DEPT_ADMIN.CLASS C WHERE C.CCODE = G.CCODE
SELECT CCODE, CNAME FROM DEPT_ADMIN.CLASSC WHERE NOT EXISTS (SELECT ''''X'''' FROM STUDENT_ADMIN.GRADE G WHERE C.CCODE = G.CCODE)
INSERT语句
Oracle和Microsoft SQL Server用的INSERT语句的语法是类似的。
Oracle
Microsoft SQL
INSERT INTO {table_name | view_name | select_statement} [(column_list)] {values_list | select_statement}
INSERT [INTO] { table_name [ [AS] table_alias] WITH ( <table_hint_limited> […n]) | view_name [ [AS] table_alias] | rowset_function_limited }
{ [(column_list)] { VALUES ( { DEFAULT | NULL | expression }[,…n] ) | derived_table | execute_statement } } | DEFAULT VALUES
Transact-SQL语言支持插入表和视图,但是不支持SELECT语句中的INSERT操作。如果你的Oracle程序这么做了,则必须修改。
Oracle
Microsoft SQL
INSERT INTO (SELECT SSN, CCODE, GRADE FROM GRADE) VALUES (''''111111111'''', ''''1111'''',NULL)
INSERT INTO GRADE (SSN, CCODE, GRADE) VALUES (''''111111111'''', ''''1111'''',NULL)
Transact-SQL的values_list参数提供了SQL-92标准的关键字DEFAULT,但这个在Oracle中是不支持的。当执行插入操作的时候,这个关键字给出了要用到的列的缺省值。如果给定的列没有缺省值,则插入一个NULL。如果该列不允许NULL,则返回一个错误消息。如果该列是作为一个时间片数据类型定义的,则插入下一个连续值。
关键字DEFAULT不能用于标识列。要产生下一个连续值,则有IDENTITY属性的列一定不能列入column_list或者values_clause。你不一定非要用DEFAUL关键字来获得一列的缺省值。在Oracle中,如果该列没有被column_list引用并且它有一个缺省值,则缺省值将放入列中。这是执行移植时最兼容的方法。
一个有用的Transact-SQL选项(EXECute procedure_name)是执行一个过程并且用管道把它的输出值输出到一个目标表或者视图。Oracle不允许你这样做。
UPDATE语句
因为Transact-SQL支持Oracle的UPDATE绝大多数语法,所以只需要很小的修改。
Oracle
Microsoft SQL
UPDATE {table_name | view_name | select_statement} SET [column_name(s) = {constant_value | expression | select_statement | column_list | variable_list} {where_statement}
UPDATE { table_name [ [AS] table_alias] WITH ( <table_hint_limited> […n]) view_name [ [AS] table_alias] | rowset_function_limited } SET {column_name = {expression | DEFAULT | NULL} | @variable = expression | @variable = column = expression } [,…n]
{{[FROM {<table_source>} [,…n] ]
[WHERE <search_condition>] } | [WHERE CURRENT OF { { [GLOBAL] cursor_name } | cursor_variable_name} ] } [OPTION (<query_hint> [,…n] )]
Transact-SQL的UPDATE语句不支持依赖SELECT语句的更新操作。如果你的Oracle程序这样做了,你可以把SELECT语句变成一个视图,然后 上一页 [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] ... 下一页 >> [Access]sql随机抽取记录 [Access]ASP&SQL让select查询结果随机排序的实现方法 [聊天工具]企业邮件系统的利器----FoxMail Server [系统软件]OPEN SERVER 5.0.5安装EXP300阵列柜 [系统软件]SQL语句性能优化--LECCO SQL Expert [系统软件]关于Windows2000Server的灾难恢复 [常用软件][网络]下载服务革命性风暴Poco Server评测 [C语言系列]动态创建SQL Server数据库、表、存储过程等架构信… [C语言系列]SQL Server到DB2连接服务器的实现 [C语言系列]SQL Server到SYBASE连接服务器的实现
|