打印本文 打印本文 关闭窗口 关闭窗口
把Oracle数据库移植到Microsoft SQL Server 7.0
作者:武汉SEO闵涛  文章来源:敏韬网  点击数13395  更新时间:2009/4/22 22:06:51  文章录入:mintao  责任编辑:mintao
指定存储程序中的参数

要在一个存储程序中指定一个参数,可以使用下面给出的语法。

Oracle Microsoft SQL  Varname datatype
DEFAULT <value>;
{@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触发器中提交新值 :new INSERTED.column 取消触发器 ALTER TRIGGER DTS中的选项

 

DELETEDINSERTED是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 ON NEW.SSN = OLD.SSN

 

你可以只在当前数据库中创建一个触发器,你也可以引用当前数据库之外的对象。如果你使用所有者名称来修饰触发器,那么就用同样的方法来修饰表名。

触发器可以最多嵌套32级。如果一个触发器改变了某个表,而该表有另外一个触发器,则第二个触发器是活动的,可以调用第三个触发器,如此类推。如果链上的任何触发器引起了死循环,则嵌套级别溢出,该触发器被取消。此外,如果某表结果上的一行上的一个更新触发器同时是另一行的更新,那么更新触发器将只执行一次。

Microsoft SQL Server的公布引用完整性(declarative referential integrity,DRI)没有提供跨数据库的引用完整性定义。如果需要跨数据库的完整性,可以使用触发器。

下面的语句在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 ON语句激活的。如果该选项是ON并且当前没有突出的事务,则每一个SQL语句自动开始一个事务。如果有一个打开的事务,则不会有任何新的事务开始。打开的事务必须由用户用COMMIT TRANSACTION语句来显明的承诺,以使所有的改变生效并且释放所有的锁定。

一个显明的事务是一组由下述事务分隔符包围的SQL语句:

  • BEGIN TRANSACTION [transaction_name]
  • COMMIT TRANSACTION [transaction_name]
  • ROLLBACK TRANSACTION [transaction_name | savepoint_name]

 

在下面这个例子中,英语系被改变为文学系。请注意BEGIN TRANSACTION和COMMIT TRANSACTION语句的用法。

Oracle Microsoft SQL  INSERT INTO DEPT_ADMIN.DEPT (DEPT, DNAME)
VALUES (''''LIT'''', ''''Literature'''')
/
UPDATE DEPT_ADMIN.CLASS
SET MAJOR = ''''LIT''''
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 ON语句来开始脚本。BEGIN TRANSACTION的方法更灵活一些,而隐式的方法更适合Oracle。

 

锁定和事务孤立

Oracle和Microsoft SQL Server有着很不一样的锁定和孤立策略。当你把Oracle应用程序转化为SQL Server应用程序的时候,你必须考虑到这些不同以确保应用程序的可伸缩性。

Oracle对所有读

上一页  [1] [2] [3] [4] [5] [6] [7] [8] [9] [10]  ...  下一页 >> 

打印本文 打印本文 关闭窗口 关闭窗口