這兩天寫數據庫升級腳本
發現MSSQL和Oracle之間的轉化還是比較容易的
以下面兩個過程為例
兩者的功能相似
MSSQL腳本
/**//** 更改表名 **/
Begin
declare @tempPoTableName varchar(
)
性能對象表名
declare @tempPoSpName varchar(
)
性能過程名
declare @errorInfo varchar(
)
錯誤信息
declare @cnt int
計數器
declare @tempSQL varchar(
)
定義表名
同步表名和存儲過程游標
set @tempSQL =
declare allValues_Cursor cursor for
+CHAR(
) + CHAR(
)
set @tempSQL = @tempSQL +
select POTABLENAME
POSPNAME from PM_NEPODEF_TABLE WHERE POID>
and POID<
EXEC (@tempSQL)
OPEN allValues_Cursor
判斷是否由符合游標條件的行
如果沒有則關閉和釋放游標
異常返回
IF(@@CURSOR_ROWS =
)
BEGIN
CLOSE allValues_Cursor
DEALLOCATE allValues_Cursor
set @errorInfo =
沒有指定表名或存儲過程名!
print @errorInfo
return
END
print
開始更改原有表名……
FETCH NEXT FROM allValues_Cursor INTO @tempPoTableName
@tempPoSpName
根據給定的表名
存儲過程名 創建相應的數據存儲存儲過程
WHILE (@@FETCH_STATUS <>
)
BEGIN
print @tempPoTableName
IF (EXISTS (SELECT name from sysobjects WHERE name=@tempPoTableName))
BEGIN
set @tempSQL =
ALTER TABLE
+ @tempPoTableName+
DROP constraint PK_
+@tempPoTableName
EXEC (@tempSQL)
set @tempSQL = @tempPoTableName+
_TMP
EXEC Sp_rename @tempPoTableName
@tempSQL
END
ELSE
BEGIN
print
沒有找到表
+@tempPoTableName;
END
IF (EXISTS (SELECT name from sysobjects WHERE name=@tempPoSpName))
BEGIN
set @tempSQL =
DROP PROCEDURE
+@tempPoSpName;
EXEC (@tempSQL)
END
ELSE
BEGIN
print
沒有找到過程
+@tempPoSpName;
END
FETCH NEXT FROM allValues_Cursor INTO @tempPoTableName
@tempPoSpName
END
CLOSE allValues_Cursor
DEALLOCATE allValues_Cursor
print
結束更改原有表名……
print
END
GO
ORACLE腳本
BEGIN
DECLARE
tempPoTableName varchar
(
);
性能對象表名
tempPoSpName varchar
(
);
性能過程名
errorInfo varchar
(
);
錯誤信息
tempSQL varchar
(
);
cnt
number(
);
cnt
number(
);
定義表名
同步表名和存儲過程游標
Cursor allValues_Cursor is
select UPPER(TRIM(POTABLENAME))
UPPER(TRIM(POSPNAME)) from PM_NEPODEF_TABLE WHERE POID>
and POID<
;
BEGIN
OPEN allValues_Cursor;
判斷是否由符合游標條件的行
如果沒有則關閉和釋放游標
異常返回
DBMS_OUTPUT
PUT_LINE(
開始更改原有表名……
);
FETCH allValues_Cursor INTO tempPoTableName
tempPoSpName;
根據給定的表名
存儲過程名 創建相應的數據存儲存儲過程
WHILE allValues_Cursor%found LOOP
cnt
:=
;
cnt
:=
;
BEGIN
SELECT
INTO cnt
FROM dual WHERE exists(SELECT table_name FROM user_tables WHERE table_name = tempPoTableName);
SELECT
INTO cnt
FROM dual WHERE exists(SELECT OBJECT_NAME FROM user_procedures WHERE OBJECT_NAME = tempPoSpName);
exception
WHEN no_data_found THEN
null;
END;
IF cnt
=
THEN
DBMS_OUTPUT
PUT_LINE(tempPoTableName);
tempSQL :=
ALTER TABLE
||tempPoTableName||
DROP constraint PK_
||tempPoTableName;
EXECUTE IMMEDIATE tempSQL;
tempSQL :=
ALTER TABLE
||tempPoTableName||
RENAME TO
||tempPoTableName||
_TMP
;
EXECUTE IMMEDIATE tempSQL;
ELSE
DBMS_OUTPUT
PUT_LINE(
沒有找到表
||tempPoTableName);
END IF;
IF cnt
=
THEN
tempSQL :=
DROP PROCEDURE
||tempPoSpName;
EXECUTE IMMEDIATE tempSQL;
ELSE
DBMS_OUTPUT
PUT_LINE(
沒有找到過程
||tempPoSpName);
END IF;
FETCH allValues_Cursor INTO tempPoTableName
tempPoSpName;
END LOOP;
CLOSE allValues_Cursor;
DBMS_OUTPUT
PUT_LINE(
結束更改原有表名……
);
DBMS_OUTPUT
PUT_LINE(
);
END;
END;
/
上面兩個是無名存儲過程不需要考慮是否已經存在該過程對於有名的過程需要考慮對象是否已經存在
我是從MSSQL向Oracle轉化的
第一步修改整體結構
MSSQL的總體結構如下只需要一個begin和end中間加入變量聲明
Begin
declare
變量
過程
END
GO
Oralce的總體結構如下需要兩個begin和end一個是整個過程一個是除去申明之外的過程
BEGIN
DECLARE
變量
BEGIN
過程
END;
END;
/
第二步修改聲明變量
MSSQL需要在每個變量前面加 declare標示Oracle只需要一個declare標示此外注意修改各自的數據類型
第三步修改游標復雜的過程中離不開游標因此更改游標結構經常用到
MSSQL的游標是全局的需要建立之後再清空而Oracle的游標類似於局部變量使用完之後自動清除
MSSQL游標結構如下
set @tempSQL =
declare allValues_Cursor cursor for
+CHAR(
) + CHAR(
)
set @tempSQL = @tempSQL +
select POTABLENAME
POSPNAME from PM_NEPODEF_TABLE WHERE POID>
and POID<
游標語句
EXEC (@tempSQL)
創建游標
OPEN allValues_Cursor
打開游標
判斷是否由符合游標條件的行
如果沒有則關閉和釋放游標
異常返回
IF(@@CURSOR_ROWS =
)
BEGIN
CLOSE allValues_Cursor
DEALLOCATE allValues_Cursor
set @errorInfo =
沒有指定表名或存儲過程名!
print @errorInfo
return
END
WHILE (@@FETCH_STATUS <>
)
BEGIN
FETCH NEXT FROM allValues_Cursor INTO @tempPoTableName
@tempPoSpName
進行數據處理
END
CLOSE allValues_Cursor
關閉游標
DEALLOCATE allValues_Cursor
注銷游標
Oracle的游標是在變量中聲明定義的然後在過程中使用其結構如下
聲明中
Cursor allValues_Cursor is
select UPPER(TRIM(POTABLENAME))
UPPER(TRIM(POSPNAME)) from PM_NEPODEF_TABLE WHERE POID>
and POID<
;
聲明游標
過程中
OPEN allValues_Cursor;
打開游標
WHILE allValues_Cursor%found LOOP
FETCH allValues_Cursor INTO tempPoTableName
tempPoSpName;
處理數據
END LOOP;
CLOSE allValues_Cursor;
關閉游標
第四步修改賦值語句和比較語句MSSQL中使用Set語句來賦值Oracle中使用:=來賦值此外MSSQL中的變量習慣前面增加一個@字符在Oracle中可以刪除
第五步修改邏輯結構MSSQL中使用IF()ELSE
結構體之間都要用BEGIN和END框起來而Oracle則使用IFTHENELSEEND IF結構中間不必使用BEGIN和END此外While結構差別也類似
第六步修改各自的調用方法和函數常見的是MSSQL的EXEC (@tempSQL)對應Oracle的EXECUTE IMMEDIATE tempSQLMSSQL的print函數對應Oracle的DBMS_OUTPUTPUT_LINE()函數此外還有各自使用的數據表有所不同例如MSSQL中所有的對象都在sysobjects表中而Oracle中的表在user_tables中過程在user_procedures中等這些需要積累一些經驗
最後不要忘了檢查Oracle的所有句子必須要有分號表示結束而MSSQL中不需要即使加了也不錯幾步下來MSSQL過程就轉化成Oracle
From:http://tw.wingwit.com/Article/program/Oracle/201311/17883.html