引自:http://www.itpub.net/23129.html
1. ORACLE存儲(chǔ)過(guò)程的參數(shù)不能限定位數(shù),參數(shù)類型定位為
CHAR(5)是非法的,只能定義為CHAR,具體位數(shù)限定有調(diào)用時(shí)的實(shí)參決定,這一點(diǎn)確實(shí)與SYBASE有很大不同;
2.游標(biāo)在PL/SQL中作用極大,游標(biāo)的概念滲透到整個(gè)PL/SQL的核心,連INSERT,UPDATE等語(yǔ)句都隱含了一個(gè)隱式游標(biāo)SQL,類似SYBASE的@@ROWCOUNT等系統(tǒng)變量,在ORACLE中定義為游標(biāo)屬性SQL%ROWCOUNT;
3.ORACLE中顯示一個(gè)變量的語(yǔ)句為SELECT V_VAR FROM DUAL;
與SYBASE不同的是必須加FROM DUAL;
4.SYBASE存儲(chǔ)過(guò)程可以通過(guò)類似SELECT * FROM T_TABLE來(lái)返回?cái)?shù)據(jù)集,在ORACLE中似乎不能,所有不帶INTO的SELECT 語(yǔ)句在ORACLE存儲(chǔ)過(guò)程中是非法的。這一點(diǎn)變化帶來(lái)最大麻煩,應(yīng)為POWERBUILDER調(diào)用SYBASE存儲(chǔ)過(guò)程很喜歡這種方式。
5、在存儲(chǔ)過(guò)程中聲明參數(shù)不用加 DECLARE
6、在每個(gè)塊中只有一個(gè) DECLARE
7、參數(shù)名不用加 @ 后綴
8、每條語(yǔ)句后要加分號(hào)
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 ,無(wú)論是 read-consistent 還是 serializable 事務(wù)所以要注意SELECT FOR UPDATE的使用
移植方案
一.后臺(tái)存儲(chǔ)過(guò)程利用conv72從SYBASE轉(zhuǎn)換到ORACLE。
USAGE: conv72 [-P -F -M] <input_file_name>
-P指存儲(chǔ)過(guò)程,-F指函數(shù)
例如:conv72 -P filename.sql
轉(zhuǎn)換后,產(chǎn)生文件名字是filename.sql.sql
二.轉(zhuǎn)換后的調(diào)整。
(一)后臺(tái)存儲(chǔ)過(guò)程的調(diào)整
1、NULL
ORACLE對(duì)NULL 的條件判斷只能用: 變量 IS NULL 和變量 IS NOT NULL;
對(duì)NULL 的附值只能用:變量 := NULL;
因此需要對(duì)所有存儲(chǔ)過(guò)程中有關(guān) NULL 的操作做上述相應(yīng)調(diào)整。
2、StoO_error:=0;
所有存儲(chǔ)過(guò)程中,凡是對(duì)數(shù)據(jù)庫(kù)做有效操作之前,包括UPDATE,DELETE,INSERT以及
執(zhí)行子存儲(chǔ)過(guò)程或函數(shù),都有必要將ORACLE轉(zhuǎn)化過(guò)程中自動(dòng)加上的變量StoO_error清
零,即在操作之前加上 StoO_error:=0; 。
3、WHEN NO_DATA_FOUND THEN StoO_error :=0;
所有存儲(chǔ)過(guò)程中,對(duì)數(shù)據(jù)庫(kù)做有效操作之后,通常會(huì)用IF StoO_error != 0 THEN來(lái)
檢驗(yàn)操作成功與否。對(duì)于空操作,即WHERE 子句條件不滿足時(shí),ORACLE會(huì)產(chǎn)生例外,
而SYBASE 不會(huì)出錯(cuò)。因此為了一致,在 EXCEPTION 中 應(yīng)加入
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、事務(wù)設(shè)計(jì)
ORACLE的存儲(chǔ)過(guò)程中,COMMIT 語(yǔ)句將會(huì)把此前未提交的所有事務(wù)都提交,且對(duì)于
已提交的事務(wù),無(wú)論在后臺(tái)存儲(chǔ)過(guò)程中,還是在前臺(tái) PB 的腳本中,都無(wú)法回滾。
這與SYBASE 不同,因此事務(wù)應(yīng)該結(jié)合后臺(tái)存儲(chǔ)過(guò)程與前臺(tái) PB 腳本設(shè)計(jì)。
6、事務(wù)的調(diào)整
在ORACLE中,沒(méi)有SYBASE中事務(wù)嵌套數(shù)的概念,在后臺(tái)的存儲(chǔ)過(guò)程中,遇到
COMMIT時(shí),將把整個(gè)事務(wù)(包括前臺(tái)和后臺(tái))全部提交。而在SYBASE中,只
有當(dāng)事物數(shù)為最低級(jí)時(shí)(設(shè)計(jì)都在前臺(tái))才能提交。
由于所有事務(wù)都在前臺(tái)提交,
因此把后臺(tái)存儲(chǔ)過(guò)程中所有的COMMIT全部注釋掉。
7、時(shí)間參數(shù)調(diào)整
如果該存儲(chǔ)過(guò)程的輸入?yún)?shù)為DATE型時(shí),在POWERBUILDER中創(chuàng)建存儲(chǔ)過(guò)程
時(shí),將引發(fā)錯(cuò)誤。
為了解決此問(wèn)題,
在后臺(tái),將這種存儲(chǔ)過(guò)程的DATE型輸入?yún)?shù)
全部改為VARCHAR2型。
在存儲(chǔ)過(guò)程中,將VARCHAR2轉(zhuǎn)化為DATE,為了前后臺(tái)一致,
采用統(tǒng)一的轉(zhuǎn)化格式。
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');
在前臺(tái)POWERBUILDER中,將DATE或者DATETIME型變量轉(zhuǎn)化為STRING型,
也采用上述統(tǒng)一格式,再作為存儲(chǔ)過(guò)程的參數(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ù)窗口的后臺(tái)存儲(chǔ)過(guò)程的修改
1、通過(guò)特定表返回時(shí),WHERE子句的處理
TABLE: TEST
COLUMN: NAME VARCHAR2(20);
AGE NUMBER;
BIRTH DATE;
REMARKS VARCHAR2(30);
最后的返回語(yǔ)句如下,WHERE子句的處理中,對(duì)字符型和日期型進(jìn)行轉(zhuǎn)義處理
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型變量是該存儲(chǔ)過(guò)程的輸入?yún)?shù),則要對(duì)他進(jìn)行
單獨(dú)處理
IF VAR_AGE IS NULL THEN
CONV:=' AND AGE IS NULL ';
ELSE
CONV:=' AND AGE = ' || TO_CHAR(VAR_AGE);
END IF;
2、最后數(shù)據(jù)的返回通過(guò)表DUAL進(jìn)行
有兩種方式:
(1)、用PBDBMS.PUT_LINE。無(wú)法處理返回值為空值的情況
使用方法見(jiàn)底下示例:
注意:對(duì)不同變量類型進(jìn)行了不同處理。
(2)、用PBDBMS.PUT
該過(guò)程已經(jīng)過(guò)修改,可對(duì)各種變量類型進(jìn)行處理,不在需要在程序中對(duì)
不同類型進(jìn)行不同處理,同時(shí)也可適應(yīng)NULL值的情況。
使用方法見(jiàn)底下示例:
注意:直接使用該參數(shù),多個(gè)變量返回時(shí)注意中間加PUT(',');
另外:PBDBMS包中行最大長(zhǎng)度為255,而PUT函數(shù)不換行,因此估計(jì)
長(zhǎng)度快到255時(shí),使用PUT_LINE(',')來(lái)實(shí)現(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(',');/* 如長(zhǎng)度將超過(guò)255,此處用PUT_LINE(',')進(jìn)行換行*/
PBDBMS.PUT(I_NUM);PBDBMS.PUT(',');
PBDBMS.PUT(I_DATE);
PBDBMS.PUT_LINE(' FROM DUAL');
END;
(三)前臺(tái)腳本中嵌入式SQL語(yǔ)句的調(diào)整
1、ORACLE 存儲(chǔ)過(guò)程前臺(tái)腳本調(diào)用方式:
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 存儲(chǔ)過(guò)程前臺(tái)腳本調(diào)用方式:
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、前臺(tái)腳本中嵌入式的SQL語(yǔ)句中
(1)NULL
ORACLE對(duì)NULL 的條件判斷只能用: 字段名 IS NULL 和 字段名?IS NOT NULL;
而不能用:字段名 = NULL 和 字段名?<> NULL?
若有上述情況,應(yīng)做相應(yīng)調(diào)整。
如:select * from so_charge where receipt_nbr = null;
應(yīng)改為:select * from so_charge where receipt_nbr is null;
(2)""->''
ORACLE對(duì)字符串使用單引號(hào),而SYBASE單引號(hào)、雙引號(hào)均可
因此若有如select * from so where state="A";的語(yǔ)句
應(yīng)改為select * from so where state='A';
(3)insert -> insert into
SYBASE允許使用insert tablename...,而ORACLE必須使用
insert into tablename...,若有上述情況,應(yīng)做相應(yīng)調(diào)整。
(4)+ --> ||
字符串連接,SYBASE使用'+',而ORACLE使用'||'。?
(5)getdate() --> sysdate
取系統(tǒng)時(shí)間,SYBASE使用getdate(),而ORACLE使用sysdate。
Feedback
從sybase的存儲(chǔ)過(guò)程轉(zhuǎn)向oracle的存儲(chǔ)過(guò)程的不同點(diǎn)
引自:http://www.itpub.net/23129.html1.ORACLE存儲(chǔ)過(guò)程的參數(shù)不能限定位數(shù),參數(shù)類型定位為CHAR...
[引用提示]my god引用了該文章, 地址: http://www.cnweblog.com/pudong/archive/2007/05/18/224542.html 回復(fù) 更多評(píng)論
[引用提示]my god引用了該文章, 地址: http://www.cnweblog.com/pudong/archive/2007/05/18/224542.html 回復(fù) 更多評(píng)論
只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。 | ||
![]() |
||
網(wǎng)站導(dǎo)航:
博客園
IT新聞
Chat2DB
C++博客
博問(wèn)
管理
|
||
相關(guān)文章:
|
||