oraclesqlserver:把Oracle数据库移植到MicrosoftSQLServer7.0(4)




  引用完整性
  
  下表提供了个用来定义referential完整性约束语法比较
  
  约束 Oracle Microsoft SQL Server
  PRIMARY KEY [CONSTRAINT constra_name]
  PRIMARY KEY (col_name [, col_name2 [..., col_name16]])
  [USING INDEX storage_parameters] [CONSTRAINT constra_name]
  PRIMARY KEY [CLUSTERED | NONCLUSTERED] (col_name [, col_name2 [..., col_name16]])
  [ON segment_name]
  [NOT FOR REPLICATION]
  UNIQUE [CONSTRAINT constra_name]
  UNIQUE (col_name [, col_name2 [..., col_name16]])
  [USING INDEX storage_parameters] [CONSTRAINT constra_name]
  UNIQUE [CLUSTERED | NONCLUSTERED](col_name [, col_name2 [..., col_name16]])
  [ON segment_name]
  [NOT FOR REPLICATION]
  FOREIGN KEY [CONSTRAINT constra_name]
  [FOREIGN KEY (col_name [, col_name2 [..., col_name16]])]
  REFERENCES [owner.]ref_table [(ref_col [, ref_col2 [..., ref_col16]])]
  [ON DELETE CASCADE] [CONSTRAINT constra_name]
  [FOREIGN KEY (col_name [, col_name2 [..., col_name16]])]
  REFERENCES [owner.]ref_table [(ref_col [, ref_col2 [..., ref_col16]])]
  [NOT FOR REPLICATION]
  DEFAULT Column property, not a constra
  DEFAULT (constant_expression) [CONSTRAINT constra_name]
  DEFAULT {constant_expression | niladic-function | NULL}
  [FOR col_name]
  [NOT FOR REPLICATION]
  CHECK [CONSTRAINT constra_name]
  CHECK (expression) [CONSTRAINT constra_name]
  CHECK [NOT FOR REPLICATION] (expression)
  
   
  
  NOT FOR REPLICATION子句用来在复制过程中挂起列级别FOREIGN KEY以及CHECK约束
  
   
  
  外部键
  
  定义外部关键字语法在各种RDBMS中都是相似在外部关键字中标明列数和每数据类型必须和
  REFERENCES子句相匹配个输入到列中非空值必须在REFERENCES子句中定义表和列中存在并且被提
  及列必须有个PRIMARY KEY或者UNIQUE约束
  
  Microsoft SQL Server约束提供了在同个数据库中引用表能力要实现在数据库范围应用完整性
  以使用基于表触发器
  
  Oracle和SQL Server都支持自引用表这种表中有对同个表列或几列引用例如CLASS表中
  prereq列可以引用CLASS表中ccode列以确保个有效课程编号是作为个子句先决条件输入
  
  在Oracle中实现层叠式删除和修改是使用CASCADE DELETE子句而SQL Server用表触发器来实现同样
  功能如果需要了解更多信息请参看本章后面“SQL语言支持”部分
  
   
  
  用户定义完整性
  
  用户定义完整性允许你定义特定商业规则该规则不属于其他完整性范畴
  
   
  
  存储过程
  
  Microsoft SQL Server存储用CREATE PROCEDURE语句来接受或者返回用户提供参数除临时存储
  以外存储是在当前数据库中创建下表显示了Oracle和SQL Server语法
  
  Oracle Microsoft SQL 
  CREATE OR REPLACE PROCEDURE [user.]procedure
      [(argument [IN | OUT] datatype
      [, argument [IN | OUT] datatype]
  {IS | AS} block CREATE PROC[EDURE] procedure_name        [;number]
      [
         {@parameter data_type} [VARYING]        [= default] [OUTPUT]
      ]
      [,…n]
  [WITH
      { RECOMPILE   | ENCRYPTION |
        RECOMPILE, ENCRYPTION} ]
  [FOR REPLICATION]
  AS
      sql_statement […n]
  
   
  
  在SQL Server中临时存储是在tempdb数据库中通过在procedure_name前加上数字标记来创建
  个数字标记(#procedure_name)表示是个本地临时存储加两个数字标记(##procedure_name)表示
  是个全局临时
  
  个本地临时只能被创建它用户使用执行本地临时许可不能授予其他用户本地临时
  用户会话结束时自动删除
  
  个全局临时可以被所有SQL Server用户使用如果个全局临时被创建了所有用户都可
  以访问它并且不能显式撤回许可全局临时在最后个用户会话结束时候自动删除
  
  SQL Server存储可以有最多32级嵌套嵌套层数在被开始执行时增加在被结束
  运行时减少
  
  下面例子介绍说明了怎样用个Transact-SQL存储来代替个OraclePL/SQL封装Transact-SQL
  版本更简单SQL Server返回结果能力是在个存储中直接用SELECT语句设置不需要
  使用游标
  
  Oracle Microsoft SQL 
  CREATE OR REPLACE PACKAGE    STUDENT_ADMIN.P1 AS ROWCOUNT    NUMBER :=0;
     CURSOR C1 RETURN    STUDENT%ROWTYPE;
     FUNCTION    SHOW_RELUCTANT_STUDENTS
  (WORKVAR OUT VARCHAR2)       RETURN NUMBER;
  END P1;
  /
  
  CREATE OR REPLACE PACKAGE BODY    STUDENT_ADMIN.P1 AS CURSOR C1    RETURN STUDENT%ROWTYPE
  IS
        SELECT * FROM       STUDENT_ADMIN.STUDENT
          WHERE NOT EXISTS
        (SELECT \'X\' FROM       STUDENT_ADMIN.GRADE
        WHERE       GRADE.SSN=STUDENT.SSN) ORDER       BY SSN;


  
  FUNCTION SHOW_RELUCTANT_STUDENTS
     (WORKVAR OUT VARCHAR2) RETURN    NUMBER IS
     WORKREC STUDENT%ROWTYPE;
     BEGIN
        IF NOT C1%ISOPEN THEN OPEN C1;
        ROWCOUNT :=0;
        ENDIF;
        FETCH C1 INTO WORKREC;
        IF (C1%NOTFOUND) THEN
          CLOSE C1;
          ROWCOUNT :=0;
        ELSE
          WORKVAR := WORKREC.FNAME||\'         \'||WORKREC.LNAME||
          \', social security number         \'||WORKREC.SSN||\' is not enrolled
             in any es!\';
          ROWCOUNT := ROWCOUNT + 1;
        ENDIF;
  RETURN(ROWCOUNT); CREATE PROCEDURE
  STUDENT_ADMIN.SHOW_
  RELUCTANT_STUDENTS
  AS SELECT FNAME+\' +LNAME+\', social   security number\'+ SSN+\' is not enrolled in any  
   es!\'
  FROM STUDENT_ADMIN.STUDENT S
  WHERE NOT EXISTS
     (SELECT \'X\' FROM    STUDENT_ADMIN.GRADE G
     WHERE G.SSN=S.SSN)
  ORDER BY SSN
  RETURN@@ROWCOUNT
  GO
        EXCEPTION
  WHEN OTHERS THEN
  IF C1%ISOPEN THEN CLOSE C1;
  ROWCOUNT :=0;
  ENDIF;
  RAISE_APPLICATION_ERROR(-20001,SQLERRM);
  END SHOW_RELUCTANT_STUDENTS;
  END P1;
  /  
  
   
  
  SQL Server不支持和Oracle包或者相似构造也不支持在创建存储CREATE OR REPLACE选项
  
   
  
  延迟存储过程执行
  
  Microsoft SQL Server提供了WAITFOR允许开发人员给定个时间时间段或者事件来触发个语句块、
  存储或者事务执行这是Transact-SQL对于Oracle中dbms_lock_sleep等价
  
  WAITFOR {DELAY \'time\' | TIME \'time\'}
  
  指示Microsoft SQL Server等待直到给定时间过去以后再执行最多可以到24小时
  
  在这里
  
  DELAY
  指示Microsoft SQL Server等待直到给定数量时间过去以后才执行最多可以设置到24小时
  
  \'time\'
  需要等待时间时间可以是任何可接受datetime数据类型格式或者可以作为个本地变量给出
  但是不能指定datetime值日期部分
  
  TIME
  指示SQL Server等到指定时间
  
  例如:
  
  BEGIN
  WAITFOR TIME \'22:20\'
  
  EXECUTE update_all_stats
  
  END
  
  
   
  
  指定存储参数
  
  要在个存储中指定个参数可以使用下面给出语法
  
  Oracle Microsoft SQL 
  Varname datatype
  DEFAULT ; {@parameter data_type} [VARYING]
     [= default] [OUTPUT]
  
   
  
  触发器(Triggers)
  
  Oracle和Microsoft SQL Server都有触发器但它们在执行上有些区别
  
  描述 Oracle Microsoft SQL Server
  每表可以有触发器数 无限制 无限制
  在INSERT, UPDATE, DELETE的前执行触发器 是 否
  在INSERT, UPDATE, DELETE的后执行触发器 是 是
  语句级触发器 有 有
  行级触发器 有 无
  在执行的前检查约束 是除非触发器被取消 是另外这是DTS(Data Transformation Services)中
  个选项
  在个UPDATE或者DELETE触发器中提交旧或者以前值 :old DELETED.column
  在INSERT触发器中提交新值 : INSERTED.column
  取消触发器 ALTER TRIGGER DTS中选项
  
   
  
  DELETED和INSERTED是SQL Server为触发器创建概念上该表在结构上同触发器定义于其上表相似
  并且保存了可能被用户行动改变或者新行中该表将跟踪在Transact-SQL中变化
  这些表提供了和Oracle中行级别触发器同样功能个INSERT、UPDATE、或者DELETE语句在SQL
  Server中执行时候行被加入到触发器表中而且是同时加入到INSERTED和DELETED表中
  
  INSERTED和DELETED表同触发器表是它们有同样列名和数据类型例如如果在GRADE表中放置
  个触发器那么INSERTED和DELETED就有这样结构
  
  GRADE INSERTED DELETED
  SSN CHAR(9)
  CCODE VARCHAR(4)
  GRADE VARCHAR(2) SSN CHAR(9)
  CCODE VARCHAR(4)
  GRADE VARCHAR(2) SSN CHAR(9)
  CCODE VARCHAR(4)
  GRADE VARCHAR(2)
  
   
  
  INSERTED和DELETED表可以被触发器检查以确定要执行什么样触发器行动INSERTED表同INSERT和UPDATE
  语句起使用DELETED表则和DELETE以及UPDATE语句起使用
  
  UPDATE语句使用INSERTED和DELETED表这是进行UPDATE操作时SQL Server总是要删除旧填入
  新因此执行UPDATE时INSERTED表中行总是DELETED表中副本
  
  下面例子使用INSERTED和DELETED表来代替PL/SQL中行级别触发器个完全外部接合点被用来查
  询任意表中所有行
  
  Oracle Microsoft SQL Server
  CREATE TRIGGER STUDENT_ADMIN.TRACK_GRADES
  AFTER
  INSERT OR UPDATE OR DELETE
  ON STUDENT_ADMIN.GRADE
  FOR EACH ROW
  BEGIN
  INSERT INTO GRADE_HISTORY(
      TABLE_USER, ACTION_DATE,
      OLD_SSN, OLD_CCODE,
      OLD_GRADE, NEW_SSN,
      NEW_CCODE, NEW_GRADE)


  VALUES (USER, SYSDATE,
      :OLD.SSN, :OLD.CCODE,    
   :OLD.GRADE, :NEW.SSN,    
  
   :NEW.CCODE, :NEW.GRADE),
  END;
  CREATE TRIGGER STUDENT_ADMIN.TRACK_GRADES
  ON STUDENT_ADMIN.GRADE
  FOR INSERT, UPDATE, DELETE
  AS
  INSERT INTO GRADE_HISTORY(
     TABLE_USER, ACTION_DATE,
     OLD_SSN, OLD_CCODE, OLD_GRADE
     NEW_SSN, NEW_CCODE,    NEW_GRADE)
  SELECT USER, GETDATE,
     OLD.SSN, OLD.CCODE, OLD.GRADE,
     NEW.SSN, NEW.CCODE, NEW.GRADE
  FROM INSERTED NEW FULL OUTER    JOIN
    DELETED OLD _disibledevent=>  
   
  
  你可以只在当前数据库中创建个触发器你也可以引用当前数据库的外对象如果你使用所有者名称来
  修饰触发器那么就用同样思路方法来修饰表名
  
  触发器可以最多嵌套32级如果个触发器改变了某个表而该表有另外个触发器则第 2个触发器是活
  动可以第 3个触发器如此类推如果链上任何触发器引起了死循环则嵌套级别溢出该触发
  器被取消此外如果某表结果上行上个更新触发器同时是另更新那么更新触发器将只执
  行
  
  Microsoft SQL Server公布引用完整性(declarative referential egrityDRI)没有提供跨数据库
  引用完整性定义如果需要跨数据库完整性可以使用触发器
  
  下面语句在Transact-SQL触发器中是不被允许
  
  CREATE 语句(DATABASE, TABLE, INDEX, PROCEDURE, DEFAULT, RULE, TRIGGER, SCHEMA, 和VIEW)
  DROP 语句(TRIGGER, INDEX, TABLE, PROCEDURE, DATABASE, VIEW, DEFAULT, RULE)
  ALTER 语句(DATABASE, TABLE, VIEW, PROCEDURE, TRIGGER)
  TRUNCATE TABLE
  GRANT, REVOKE, DENY
  UPDATE STATISTICS
  RECONFIGURE
  UPDATE STATISTICS
  RESTORE DATABASE, RESTORE LOG
  LOAD LOG, DATABASE
  DISK语句
  SELECT INTO (它创建个表)
   
  
  
  如果需要了解有关触发器更多信息请参看SQL Server联机手册
  
  事务、锁定和并行
  
  本部分解释了在Oracle和Microsoft SQL Server事务是如何执行并且提供了所有数据库类型中锁定过程
  和并行问题的间区别
  
   
  
  事务
  
  在Oracle中执行插入、更新或者删除操作时自动开始事务个应用必须给出个COMMIT命令来保存
  数据库所有修改如果没有执行COMMIT所有修改都将后滚或者自动变成未完成
  
  缺省情况下Microsoft SQL Server在每次插入、更新或者删除操作的后自动执行个COMMIT语句
  据是自动保存你不能后滚任何改变你可以使用隐式或者显式事务模式来改变这个缺省行为
  
  隐式事务模式允许SQL Server像Oracle样运转这种模式是用SET IMPLICIT_TRANSACTIONS _disibledevent=>  WHERE MAJOR = \'ENG\'
  /
  UPDATE STUDENT_ADMIN.STUDENT
  SET MAJOR = \'LIT\'
  WHERE MAJOR = \'ENG\'
  /
  DELETE FROM DEPT_ADMIN.DEPT
  WHERE DEPT = \'ENG\'
  /
  COMMIT
  / BEGIN TRANSACTION
  
  INSERT INTO DEPT_ADMIN.DEPT (DEPT, DNAME)
  VALUES (\'LIT\', \'Literature\')
  
  UPDATE DEPT_ADMIN.CLASS
  SET DEPT = \'LIT\'
  WHERE DEPT = \'ENG\'
  
  UPDATE STUDENT_ADMIN.STUDENT
  SET MAJOR = \'LIT\'
  WHERE MAJOR = \'ENG\'
  
  DELETE FROM DEPT_ADMIN.DEPT
  WHERE DEPT = \'ENG\'
  
  COMMIT TRANSACTION
  GO
  
   
  
  所有显明事务必须用BEGIN TRANSACTION...COMMIT TRANSACTION语句封闭SAVE TRANSACTION语句功能
  同Oracle中SAVEPOINT命令是在事务中设置个保存点这样就可以进行部分后滚(roll back)
  了
  
  事务可以嵌套如果出现了这种情况最外层对创建并提交事务内部对跟踪嵌套层当遇到个嵌
  套事务时@@TRANCOUNT就增加通常这种显然事务嵌套发生在存储或者有BEGIN…COMMIT对
  互相触发器中尽管事务可以嵌套但是对ROLLBACK TRANSACTION语句行为影响是很小
  
  在存储过程和触发器中BEGIN TRANSACTION语句个数必须和COMMIT TRANSACTION语句个数相匹配包含
  不匹配BEGIN TRANSACTION和COMMIT TRANSACTION语句存储过程和触发器在运行时候会产生
  息语法允许在个事务中包含BEGIN TRANSACTION和COMMIT TRANSACTION语句对存储过程和触发器
  
  只要情况许可就应该把个大事务分成几个较小事务确保每个事务都在个单独batch中有完整


  定义为了把可能并行冲突减到最小事务既不应该跨越多个batch也不应该等待用户输入把多个事务
  组合到个运行时间较长事务中会给恢复时间带来消极影响并且还会造成并行问题
  
  在使用ODBC编程时候你可以通过使用SQLSetConnectOption来选择显式或者隐式事务模式究竟该
  选择哪种模式要视AUTOCOMMIT连接选项情况而定如果AUTOCOMMIT是ON(缺省)你就是在显式模式中
  如果AUTOCOMMIT是OFF则在隐式模式下
  
  如果你通过SQL Server Query Analyzer或者其他查询工具使用脚本你可以显式包括个上面提到
  BEGIN TRANSACTION语句也可以利用SET IMPLICIT_TRANSACTIONS _disibledevent=>


  有可能会读到未提交或者污损数据;在事务结束以前数据可能会改变数据集中行可能出现也可能
  消失这个选项同个事务中在所有SELECT语句中设定所有表为NOLOCK效果是这是 4种孤立级
  别中限制性最小只有在你已经彻底搞清楚了它将对你应用结果精确度有什么样影响
  前提下才能使用这种选择
  
   
  
  SQL Server有两种思路方法实现Oracle中READ _disibledevent=>  将减少并行性
  
   
  
  表级别锁定
  
  Microsoft SQL Server可以用SELECT…table_name (TABLOCK)语句来锁定整个表这和Oracle LOCK
  TABLE…IN SHARE MODE语句是该锁定允许其他人读取个表但是禁止他们修改该表缺省情况下
  锁定将维持到语句结束如果你同时加上了HOLDLOCK关键字(SELECT…table_name (TABLOCK HOLDLOCK))
  表锁定将直维持到事务结束
  
  可以用SELECT…table_name (TABLOCKX)语句在个SQL Server表上设置个独占锁定该语句请求个表
  上独占锁定该锁定禁止其他人读取和修改该表并且将直维持到命令或者事务结束这同Oracle中
  TABLE…IN EXCLUSIVE MODE语句功能是
  
  SQL Server没有为显式锁定请求提供NOWAIT选项
  
  
  
   
  
  锁定升级
  
  当个查询向表请求行时Microsoft SQL Server自动生成个页级别锁定但是如果查询请求表中
  大部分行时SQL Server将把锁定从页级别升级到表级别这个过程叫做锁定升级
  
  锁定增加使那些产生较大结果集扫描和操作更加有效它减少了锁定管理开销缺少WHERE子句
  SQL语句般都要造成锁定增加
  
  在读取操作中如果个共享页级别锁定增加为个表锁定时将应用个共享表锁定(TABLOCK)在下
  列情况下应用共享表级别锁定:
  
  使用了HOLDLOCK或者SET TRANSACTION ISOLATION LEVEL SERIALIZABLE语句
  优化器选择了个表扫描
  表中积累共享锁定数目超过锁定升级极限
  表中缺省锁定升级极限是200页但是该极限可以用最小和最大范围定制为依赖于表尺寸个百分比
  欲了解有关锁定升级极限更多信息请参看SQL Server联机手册
  
  在个写操作中个UPDATE锁定被升级为个表锁定时应用个独占表锁定(TABLOCKX)独占表锁定
  在下列情况下使用:
  
  更新或者删除操作无索引可用
  表中有独占锁定数目超过锁定升级上限
  创建了个分簇索引
   
  
  Oracle不能升级行级别锁定这将导致些包含了FOR UPDATE子句查询出问题例如假设STUDENT表有
  100000行数据并且个Oracle用户给出下列语句:
  
  SELECT * FROM STUDENT FOR UPDATE
  
   
  
  这个语句强制Oracle RDBMS依次锁定STUDENT表行;这将花去段时间它永远也不会要求升级锁定到整
  个表
  
  在SQL Server同样查询是:
  
  SELECT * FROM STUDENT (UPDLOCK)
  
   
  
  当这个查询运行时候页级别锁定升级为表级别锁定后者更加有效并且明显要快
  
  死锁
  
  当个进程锁定了另个进程需要页或者表时候而第 2个进程又锁定了第个进程需要这个
  时候就会发生死锁死锁也叫抱死SQL Server自动探测和解决死锁如果找到个死锁服务器将终止完
  成了抱死用户进程
  
   
  
  在每次数据修改的后代码需要检查1205号消息这个消息指出个死锁如果返回这个消息
  介绍说明发生了个死锁并且事务已经后滚在这种情况下应用必须重新开始这个事务
  
  死锁般可以通过些简单技术加以避免:
  
  在你应用各部分以同样顺序访问表
  在每个表上使用分簇索引以强制个显式行顺序
  使事务简短
  欲了解详细信息请参阅Microsoft Knowledge Base文章“Detecting and Avoiding Deadlocks in
   Microsoft SQL Server”
  
   
  
  远程事务
  
  在Oracle中执行远程事务你必须通过个数据库连接访问远程数据库节点在SQL Server中你必须访


  问个远程服务器远程服务器是台运行SQL Server服务器用户可以用他们本地服务器访问该服
  务器当某个服务器被设置为远程服务器用户就可以在其上使用系统过程和存储过程而不需要显式
  录到上面
  
  远程服务器是成对设置你必须配置两台服务器使它们互相把对方当作远程服务器每台服务器
  字都必须用sp_addlinkedserver系统存储过程或者SQL Server Enterprise Manager加到伙伴服务器上
  
  设置完远程服务器以后你可以用sp_addremotelogin系统存储过程或者SQL Server Enterprise Manager
  来为那些必须访问远程服务器用户设置远程登录账号在这步完成以后你还必须赋予他们执行存储
  过程权限
  
  然后用EXECUTE语句来在远程服务器上执行过程这个例子在远程服务器STUDSVR1上执行了validate_student
  存储过程并且将指明成功或者失败返回情况存储在@retvalue1中:
  
  DECLARE @retvalue1
  EXECUTE @retvalue = STUDSVR1.student_db.student_admin.validate_student \'111111111\'
  
  
   
  
  欲了解详细信息请参看SQL Server联机手册
  
   
  
  分布事务
  
  如果修改两个或者更多数据库节点上Oracle就自动个分布式事务SQL Server分布式事务使
  用包含在SQL Server中微软分布事务协调器(Microsoft Distributed Transaction CoordinatorMS DTC)
  中两步提交服务(two-phase commit services)
  
  缺省情况下SQL Server必须被通知参和分布事务SQL Server参和个MS DTC事务可以用下面方式中
  种来存储:
  
  BEGIN DISTRIBUTED TRANSACTION语句该语句开始个新MS DTC事务
  个客户端应用直接DTC事务接口
  在下例中注意对本地表GRADE和远程表CLASS分布式更新(使用_name过程):
  
  BEGIN DISTRIBUTED TRANSACTION
  UPDATE STUDENT_ADMIN.GRADE
  
  SET GRADE = \'B+\' WHERE SSN = \'111111111\' AND CCODE = \'1234\'
  
  DECLARE @retvalue1
  
  EXECUTE @retvalue1 = CLASS_SVR1.dept_db.dept_admin._name \'1234\', \'Basketweaving\'
  
  COMMIT TRANSACTION
  
  GO
  
  
   
  
  如果不能完成事务则通过ROLLBACK TRANSACTION语句终止该事务如果失败或者参和资源管理器
  失败MS DTC终止该事务MS DTC不支持分布式存储点或者是SAVE TRANSACTION语句如果个MS DTC事务
  失败或者后滚则整个事务退回到分布式事务起点而不理会任何存储点
  
  两步提交处理
  
  Oracle和MS DTC两步提交机制在操作上是相似在SQL Server两步提交事务管理器请求每个参
  和资源管理器准备提交如果有任何资源管理器没有准备好事务管理器就向和事务相关所有成员广播
  个异常中断决定
  
  如果所有资源管理器都能成功准备事务管理器就广播个提交决定这是提交处理第 2步个资
  源管理器准备好后事务究竟是提交了还是失败了点还是拿不准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_hs*/]
  [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 _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不支持OracleSTART WITH…CONNECT BY子句在SQL Server中你可以用创建个执行同样任
  务存储过程来代替
  
  SQL Server不支持OracleINTERSECT和MINUS集合SQL ServerEXISTS和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 ( […n])
       | view_name [ [AS] table_alias]
       | row_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-SQLvalues_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支持OracleUPDATE绝大多数语法所以只需要很小修改
  
  Oracle Microsoft SQL 
  
Tags:  oracle数据库 sqlserver7.0 sqlserver数据库 oraclesqlserver

延伸阅读

最新评论

发表评论