这两天写数据库升级脚本,发现MSSQL和Oracle之间的转化还是比较容易的。 以下面两个过程为例。两者的功能相似。 1.MSSQL脚本 1 /** 更改表名 **/ 2 Begin 3 declare @tempPoTableName varchar(50)--性能对象表名 4 declare @tempPoSpName varchar(50) --性能过程名 5 declare @errorInfo varchar(200) --错误信息 6 declare @cnt int --计数器 7 8 declare @tempSQL varchar(1000) 9 10 --定义表名、同步表名和存储过程游标 11 set @tempSQL = '' declare allValues_Cursor cursor for ''+CHAR(13) + CHAR(10) 12 set @tempSQL = @tempSQL + '' select POTABLENAME,POSPNAME from PM_NEPODEF_TABLE WHERE POID>110499 and POID<110580'' 13 EXEC (@tempSQL) 14 15 OPEN allValues_Cursor 16 17 --判断是否由符合游标条件的行,如果没有则关闭和释放游标,异常返回 18 IF(@@CURSOR_ROWS = 0 ) 19 BEGIN 20 CLOSE allValues_Cursor 21 DEALLOCATE allValues_Cursor 22 set @errorInfo = ''没有指定表名或存储过程名!'' 23 print @errorInfo 24 return 25 END 26 27 print ''开始更改原有表名……'' 28 FETCH NEXT FROM allValues_Cursor INTO @tempPoTableName,@tempPoSpName 29 --根据给定的表名、存储过程名 创建相应的数据存储存储过程 30 WHILE (@@FETCH_STATUS <> -1) 31 BEGIN 32 print @tempPoTableName 33 34 IF (EXISTS (SELECT name from sysobjects WHERE name=@tempPoTableName)) 35 BEGIN 36 set @tempSQL = ''ALTER TABLE ''+ @tempPoTableName+'' DROP constraint PK_''+@tempPoTableName 37 EXEC (@tempSQL) 38 set @tempSQL = @tempPoTableName+''_TMP'' 39 EXEC Sp_rename @tempPoTableName,@tempSQL 40 END 41 ELSE 42 BEGIN 43 print ''没有找到表''+@tempPoTableName; 44 END 45 46 IF (EXISTS (SELECT name from sysobjects WHERE name=@tempPoSpName)) 47 BEGIN 48 set @tempSQL = ''DROP PROCEDURE ''+@tempPoSpName; 49 EXEC (@tempSQL) 50 END 51 ELSE 52 BEGIN 53 print ''没有找到过程''+@tempPoSpName; 54 END 55 56 FETCH NEXT FROM allValues_Cursor INTO @tempPoTableName,@tempPoSpName 57 END 58 CLOSE allValues_Cursor 59 DEALLOCATE allValues_Cursor 60 print ''结束更改原有表名……'' 61 print ''------------------------'' 62 END 63 GO
2.ORACLE脚本 1 BEGIN 2 DECLARE 3 tempPoTableName varchar2(50);--性能对象表名 4 tempPoSpName varchar2(50); --性能过程名 5 errorInfo varchar2(200); --错误信息 6 tempSQL varchar2(1000); 7 cnt1 number(1); 8 cnt2 number(2); 9 10 --定义表名、同步表名和存储过程游标 11 Cursor allValues_Cursor is 12 select UPPER(TRIM(POTABLENAME)),UPPER(TRIM(POSPNAME)) from PM_NEPODEF_TABLE WHERE POID>110499 and POID<110580; 13 14 BEGIN 15 OPEN allValues_Cursor; 16 17 --判断是否由符合游标条件的行,如果没有则关闭和释放游标,异常返回 18 19 DBMS_OUTPUT.PUT_LINE(''开始更改原有表名……''); 20 FETCH allValues_Cursor INTO tempPoTableName,tempPoSpName; 21 --根据给定的表名、存储过程名 创建相应的数据存储存储过程 22 WHILE allValues_Cursor%found LOOP 23 24 cnt1:=0; 25 cnt2:=0; 26 BEGIN 27 SELECT 1 INTO cnt1 FROM dual WHERE exists(SELECT table_name FROM user_tables WHERE table_name = tempPoTableName); 28 SELECT 1 INTO cnt2 FROM dual WHERE exists(SELECT OBJECT_NAME FROM user_procedures WHERE OBJECT_NAME = tempPoSpName); 29 exception 30 WHEN no_data_found THEN 31 null; 32 END; 33 34 IF cnt1 = 1 THEN 35 DBMS_OUTPUT.PUT_LINE(tempPoTableName); 36 tempSQL := ''ALTER TABLE ''||tempPoTableName||'' DROP constraint PK_''||tempPoTableName; 37 EXECUTE IMMEDIATE tempSQL; 38 tempSQL := ''ALTER TABLE ''||tempPoTableName||'' RENAME TO ''||tempPoTableName||''_TMP''; 39 EXECUTE IMMEDIATE tempSQL; 40 ELSE 41 DBMS_OUTPUT.PUT_LINE(''没有找到表''||tempPoTableName); 42 END IF; 43 44 IF cnt2 = 1 THEN 45 tempSQL := ''DROP PROCEDURE ''||tempPoSpName; 46 EXECUTE IMMEDIATE tempSQL; 47 ELSE 48 DBMS_OUTPUT.PUT_LINE(''没有找到过程''||tempPoSpName); 49 END IF; 50 51 FETCH allValues_Cursor INTO tempPoTableName,tempPoSpName; 52 END LOOP; 53 CLOSE allValues_Cursor; 54 DBMS_OUTPUT.PUT_LINE(''结束更改原有表名……''); 55 DBMS_OUTPUT.PUT_LINE(''------------------------''); 56 END; 57 END; 58 / 上面两个是无名存储过程,不需要考虑是否已经存在该过程。对于有名的过程需要考虑对象是否已经存在。 我是从MSSQL向Oracle转化的。 第一步,修改整体结构。 MSSQL的总体结构如下,只需要一个begin和end,中间加入变量声明。 1 Begin 2 declare --变量 3 --过程 4 END 5 GO Oralce的总体结构如下,需要两个begin和end,一个是整个过程,一个是除去申明之外的过程。 1 BEGIN 2 DECLARE 3 --变量 4 BEGIN 5 --过程 6 END; 7 END; 8 / 第二步,修改声明变量。 MSSQL需要在每个变量前面加 declare标示,Oracle只需要一个declare标示。此外注意修改各自的数据类型。 第三步,修改游标。复杂的过程中离不开游标。因此更改游标结构经常用到。 MSSQL的游标是全局的,需要建立之后再清空。而Oracle的游标类似于局部变量,使用完之后,自动清除。 MSSQL游标结构如下: set @tempSQL = '' declare allValues_Cursor cursor for ''+CHAR(13) + CHAR(10) set @tempSQL = @tempSQL + '' select POTABLENAME,POSPNAME from PM_NEPODEF_TABLE WHERE POID>110499 and POID<110580'' --游标语句
EXEC (@tempSQL) --1.创建游标
OPEN allValues_Cursor --2.打开游标
--判断是否由符合游标条件的行,如果没有则关闭和释放游标,异常返回 IF(@@CURSOR_ROWS = 0 ) BEGIN CLOSE allValues_Cursor DEALLOCATE allValues_Cursor set @errorInfo = ''没有指定表名或存储过程名!'' print @errorInfo return END
WHILE (@@FETCH_STATUS <> -1) BEGIN FETCH NEXT FROM allValues_Cursor INTO @tempPoTableName,@tempPoSpName --3进行数据处理
END
CLOSE allValues_Cursor --4.关闭游标
DEALLOCATE allValues_Cursor --5.注销游标 Oracle的游标是在变量中声明定义的,然后在过程中使用。其结构如下:
1 --声明中 2 Cursor allValues_Cursor is 3 select UPPER(TRIM(POTABLENAME)),UPPER(TRIM(POSPNAME)) from PM_NEPODEF_TABLE WHERE POID>110499 and POID<110580; 4 --1.声明游标 5 --过程中 6 OPEN allValues_Cursor; 7 --2.打开游标 8 9 WHILE allValues_Cursor%found LOOP 10 FETCH allValues_Cursor INTO tempPoTableName,tempPoSpName; 11 --3.处理数据 12 13 END LOOP; 14 CLOSE allValues_Cursor; 15 --4.关闭游标 第四步修改赋值语句和比较语句。MSSQL中使用Set语句来赋值,Oracle中使用:=来赋值。此外MSSQL中的变量习惯前面增加一个@字符,在Oracle中可以删除。 第五步修改逻辑结构。MSSQL中使用IF()....ELSE.... ,结构体之间都要用BEGIN和END框起来。而Oracle则使用IF...THEN...ELSE..END IF结构,中间不必使用BEGIN和END。此外While结构差别也类似。 第五步修改逻辑结构。MSSQL中使用IF()....ELSE....,结构体之间都要用BEGIN和END框起来。而Oracle则使用IF...THEN...ELSE..END IF结构,中间不必使用BEGIN和END。此外While结构差别也类似。 第六步修改各自的调用方法和函数。常见的是MSSQL的EXEC (@tempSQL),对应Oracle的EXECUTE IMMEDIATE tempSQL。MSSQL的print函数,对应Oracle的DBMS_OUTPUT.PUT_LINE('''')函数。此外还有各自使用的数据表,有所不同。例如MSSQL中所有的对象都在sysobjects表中,而Oracle中的表在user_tables中,过程在user_procedures中等。这些需要积累一些经验。 最后不要忘了检查,Oracle的所有句子,必须要有分号表示结束。而MSSQL中不需要,即使加了也不错。几步下来,MSSQL过程就转化成Oracle。
(责任编辑:admin) |