熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Oracle >> 正文

Oracle與MSSQL過程之間的轉化

2013-11-13 16:08:32  來源: Oracle 
這兩天寫數據庫升級腳本發現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 POTABLENAMEPOSPNAME 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_OUTPUTPUT_LINE(開始更改原有表名……);
    FETCH  allValues_Cursor INTO tempPoTableNametempPoSpName;
    根據給定的表名存儲過程名 創建相應的數據存儲存儲過程
    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_OUTPUTPUT_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_OUTPUTPUT_LINE(沒有找到表||tempPoTableName);
    END IF;
    
    IF cnt =  THEN
        tempSQL := DROP PROCEDURE ||tempPoSpName;
        EXECUTE IMMEDIATE tempSQL;
    ELSE
        DBMS_OUTPUTPUT_LINE(沒有找到過程||tempPoSpName);
    END IF;
    
        FETCH allValues_Cursor INTO tempPoTableNametempPoSpName;
    END LOOP;
    CLOSE allValues_Cursor;
    DBMS_OUTPUTPUT_LINE(結束更改原有表名……);
    DBMS_OUTPUTPUT_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 POTABLENAMEPOSPNAME 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 tempPoTableNametempPoSpName;
        處理數據

    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
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.