鷹翔宇空

          學習和生活

          BlogJava 首頁 新隨筆 聯(lián)系 聚合 管理
            110 Posts :: 141 Stories :: 315 Comments :: 1 Trackbacks

          引自:http://www.itpub.net/23129.html

          1. ORACLE存儲過程的參數(shù)不能限定位數(shù),參數(shù)類型定位為
          CHAR(5)是非法的,只能定義為CHAR,具體位數(shù)限定有調用時的實參決定,這一點確實與SYBASE有很大不同;
          2.游標在PL/SQL中作用極大,游標的概念滲透到整個PL/SQL的核心,連INSERT,UPDATE等語句都隱含了一個隱式游標SQL,類似SYBASE的@@ROWCOUNT等系統(tǒng)變量,在ORACLE中定義為游標屬性SQL%ROWCOUNT;
          3.ORACLE中顯示一個變量的語句為SELECT V_VAR FROM DUAL;
          與SYBASE不同的是必須加FROM DUAL;
          4.SYBASE存儲過程可以通過類似SELECT * FROM T_TABLE來返回數(shù)據(jù)集,在ORACLE中似乎不能,所有不帶INTO的SELECT 語句在ORACLE存儲過程中是非法的。這一點變化帶來最大麻煩,應為POWERBUILDER調用SYBASE存儲過程很喜歡這種方式。

          5、在存儲過程中聲明參數(shù)不用加 DECLARE

          6、在每個塊中只有一個 DECLARE

          7、參數(shù)名不用加 @ 后綴

          8、每條語句后要加分號

          9、變量附值不同:
          myvalue:='abc';
          select @myvalue='abc'

          SELECT EMPNO into :emp from EMP WHERE ...;
          SELECT @emp=EMPNO from emp WHERE...

          10、在TRIGGER 中出現(xiàn)exception 不用加ROLLBACK命令

          11、oracle 不使用 read locks ,無論是 read-consistent 還是 serializable 事務所以要注意SELECT FOR UPDATE的使用

          移植方案

          一.后臺存儲過程利用conv72從SYBASE轉換到ORACLE。

          USAGE: conv72 [-P -F -M] <input_file_name>
          -P指存儲過程,-F指函數(shù)
          例如:conv72 -P filename.sql
          轉換后,產(chǎn)生文件名字是filename.sql.sql



          二.轉換后的調整。


          (一)后臺存儲過程的調整

          1、NULL
          ORACLE對NULL 的條件判斷只能用: 變量 IS NULL 和變量 IS NOT NULL;
          對NULL 的附值只能用:變量 := NULL;
          因此需要對所有存儲過程中有關 NULL 的操作做上述相應調整。

          2、StoO_error:=0;
          所有存儲過程中,凡是對數(shù)據(jù)庫做有效操作之前,包括UPDATE,DELETE,INSERT以及
          執(zhí)行子存儲過程或函數(shù),都有必要將ORACLE轉化過程中自動加上的變量StoO_error清
          零,即在操作之前加上 StoO_error:=0; 。

          3、WHEN NO_DATA_FOUND THEN StoO_error :=0;
          所有存儲過程中,對數(shù)據(jù)庫做有效操作之后,通常會用IF StoO_error != 0 THEN來
          檢驗操作成功與否。對于空操作,即WHERE 子句條件不滿足時,ORACLE會產(chǎn)生例外,
          而SYBASE 不會出錯。因此為了一致,在 EXCEPTION 中 應加入
          WHEN NO_DATA_FOUND THEN StoO_error :=0;

          4、示例:
          StoO_error :=0;/*操作之前加上 StoO_error:=0*/

          BEGIN
          DELETE BOAD
          WHERE (EXCH_ID = i_exch_id) AND (SWT_ID = i_swt_id)
          AND (FRAME_NBR = i_frame_nbr) AND (SHELF_NBR = i_shelf_nbr)
          AND (BOAD_NBR = i_boad_nbr);
          StoO_rowcnt := SQL%ROWCOUNT;
          EXCEPTION
          WHEN NO_DATA_FOUND THEN
          StoO_error :=0;
          WHEN OTHERS THEN
          StoO_error := SQLCODE;
          END;

          IF StoO_error != 0 THEN
          BEGIN
          ROLLBACK TO SAVEPOINT aa;
          i_status := -1 ;
          RETURN /* */;
          END;
          END IF;
          5、事務設計
          ORACLE的存儲過程中,COMMIT 語句將會把此前未提交的所有事務都提交,且對于
          已提交的事務,無論在后臺存儲過程中,還是在前臺 PB 的腳本中,都無法回滾。
          這與SYBASE 不同,因此事務應該結合后臺存儲過程與前臺 PB 腳本設計。

          6、事務的調整
          在ORACLE中,沒有SYBASE中事務嵌套數(shù)的概念,在后臺的存儲過程中,遇到
          COMMIT時,將把整個事務(包括前臺和后臺)全部提交。而在SYBASE中,只
          有當事物數(shù)為最低級時(設計都在前臺)才能提交。

          由于所有事務都在前臺提交,
          因此把后臺存儲過程中所有的COMMIT全部注釋掉。



          7、時間參數(shù)調整

          如果該存儲過程的輸入?yún)?shù)為DATE型時,在POWERBUILDER中創(chuàng)建存儲過程
          時,將引發(fā)錯誤。

          為了解決此問題,

          在后臺,將這種存儲過程的DATE型輸入?yún)?shù)
          全部改為VARCHAR2型。
          在存儲過程中,將VARCHAR2轉化為DATE,為了前后臺一致,
          采用統(tǒng)一的轉化格式。

          i_start_DATE:=TO_DATE(i_start_string,'YYYY/MM/DD HH24:MI:SS');
          i_end_date :=TO_DATE(i_end_string, 'YYYY/MM/DD HH24:MI:SS');

          在前臺POWERBUILDER中,將DATE或者DATETIME型變量轉化為STRING型,
          也采用上述統(tǒng)一格式,再作為存儲過程的參數(shù)。

          v_STRING=STRING(v_DATE, 'YYYY/MM/DD HH:MM:SS')
          v_STRING=STRING(v_DATETIME,'YYYY/MM/DD HH:MM:SS')


          (二)用于數(shù)據(jù)窗口的后臺存儲過程的修改

          1、通過特定表返回時,WHERE子句的處理


          TABLE: TEST

          COLUMN: NAME VARCHAR2(20);
          AGE NUMBER;
          BIRTH DATE;
          REMARKS VARCHAR2(30);

          最后的返回語句如下,WHERE子句的處理中,對字符型和日期型進行轉義處理

          PBDBMS.PUT_LINE('SELECT NAME,AGE,BIRTH,REMARKS ')
          PBDBMS.PUT_LINE(' FROM TEST ');
          str_where:=' WHERE NAME='|| ''''||VAR_NAME||''''
          ||'AND AGE =' || TO_CHAR(VAR_AGE)
          ||'AND BIRTH=' || ''''||TO_CHAR(VAR_BIRTH)||'''';
          PBDBMS.PUT_LINE(str_where);

          注意:
          如果NUMBER型變量是該存儲過程的輸入?yún)?shù),則要對他進行
          單獨處理
          IF VAR_AGE IS NULL THEN
          CONV:=' AND AGE IS NULL ';
          ELSE
          CONV:=' AND AGE = ' || TO_CHAR(VAR_AGE);
          END IF;


          2、最后數(shù)據(jù)的返回通過表DUAL進行

          有兩種方式:
          (1)、用PBDBMS.PUT_LINE。無法處理返回值為空值的情況
          使用方法見底下示例:
          注意:對不同變量類型進行了不同處理。

          (2)、用PBDBMS.PUT
          該過程已經(jīng)過修改,可對各種變量類型進行處理,不在需要在程序中對
          不同類型進行不同處理,同時也可適應NULL值的情況。
          使用方法見底下示例:
          注意:直接使用該參數(shù),多個變量返回時注意中間加PUT(',');

          另外:PBDBMS包中行最大長度為255,而PUT函數(shù)不換行,因此估計
          長度快到255時,使用PUT_LINE(',')來實現(xiàn)換行目的。

          PROCEDURE AAA
          (I_SO_NBR VARCHAR2)
          IS
          I_NUM INTEGER;
          i_date date;
          I_NAME VARCHAR2(50);
          I_COV VARCHAR2(100);
          I_COV2 VARCHAR2(100);
          BEGIN
          /* 第一種方式*/
          I_COV:= ' SELECT '||''''||I_NAME||''''||','||TO_CHAR(I_NUM)||','||''''||TO_CHAR(I_DATE)||'''';
          I_COV2:=' FROM DUAL';

          PBDBMS.PUT_LINE(i_cov);
          PBDBMS.PUT_LINE(I_cov2);

          /*第二種方式*/
          PBDBMS.PUT_LINE('SELECT ');
          PBDBMS.PUT(I_NAME);
          PBDBMS.PUT(',');/* 如長度將超過255,此處用PUT_LINE(',')進行換行*/

          PBDBMS.PUT(I_NUM);PBDBMS.PUT(',');
          PBDBMS.PUT(I_DATE);
          PBDBMS.PUT_LINE(' FROM DUAL');

          END;



          (三)前臺腳本中嵌入式SQL語句的調整

          1、ORACLE 存儲過程前臺腳本調用方式:
          DECLARE sosp_cust_i PROCEDURE FOR sosp_cust_i
          (:name,:reg_nbr,:li_cust_cat_id,吐舌osition,
          null,吐舌arent_id) ;
          execute sosp_cust_i;


          SYBASE 存儲過程前臺腳本調用方式:
          DECLARE sosp_cust_i PROCEDURE FOR sosp_cust_i
          @name = :ls_name,
          @reg_nbr = :ls_regnbr,
          @cat_id = :ii_cust_cat,
          @position = null,
          @type_id = :ii_cust_type,
          @parent_id = :ll_parent_id ;
          execute sosp_cust_i;


          2、前臺腳本中嵌入式的SQL語句中
          (1)NULL
          ORACLE對NULL 的條件判斷只能用: 字段名 IS NULL 和 字段名?IS NOT NULL;
          而不能用:字段名 = NULL 和 字段名?<> NULL?
          若有上述情況,應做相應調整。
          如:select * from so_charge where receipt_nbr = null;
          應改為:select * from so_charge where receipt_nbr is null;

          (2)""->''
          ORACLE對字符串使用單引號,而SYBASE單引號、雙引號均可
          因此若有如select * from so where state="A";的語句
          應改為select * from so where state='A';

          (3)insert -> insert into
          SYBASE允許使用insert tablename...,而ORACLE必須使用
          insert into tablename...,若有上述情況,應做相應調整。

          (4)+ --> ||
          字符串連接,SYBASE使用'+',而ORACLE使用'||'。?

          (5)getdate() --> sysdate
          取系統(tǒng)時間,SYBASE使用getdate(),而ORACLE使用sysdate。

          posted on 2006-06-07 09:30 TrampEagle 閱讀(1970) 評論(1)  編輯  收藏 所屬分類: datebase

          Feedback

          # 從sybase的存儲過程轉向oracle的存儲過程的不同點[TrackBack] 2007-05-18 09:32 my god
          從sybase的存儲過程轉向oracle的存儲過程的不同點 引自:http://www.itpub.net/23129.html1.ORACLE存儲過程的參數(shù)不能限定位數(shù),參數(shù)類型定位為CHAR...
          [引用提示]my god引用了該文章, 地址: http://www.cnweblog.com/pudong/archive/2007/05/18/224542.html  回復  更多評論
            

          主站蜘蛛池模板: 上杭县| 西畴县| 吴川市| 潢川县| 厦门市| 柯坪县| 甘孜| 游戏| 尚义县| 江源县| 平遥县| 扎赉特旗| 五原县| 扶余县| 外汇| 广丰县| 靖宇县| 宜宾市| 安庆市| 丰台区| 汨罗市| 定襄县| 监利县| 沙河市| 沅江市| 元朗区| 光泽县| 云梦县| 前郭尔| 阿勒泰市| 永春县| 凤山县| 延庆县| 榆社县| 奉化市| 霍林郭勒市| 荆州市| 虎林市| 瓦房店市| 南乐县| 万荣县|