2011-10-25 111 views
1

我試圖將存儲過程從MySQL移植到Oracle,並且遇到了很多麻煩。我已經閱讀了Oracle文檔,並且在做非常基本的事情時遇到了困難,例如正確地聲明變量。我希望有人能告訴我如何正確地聲明和設置變量。將MySQL存儲過程移植到Oracle

我的存儲過程用於將值添加到兩個不同的表中,並確保它正確映射並且外鍵沒有被違反。

這裏是我的MySQL代碼:

CREATE [email protected]% PROCEDURE proc_add_entry(IN theName vARCHAR(50), IN theKey VARCHAR(50), IN theOtherData VARCHAR(50), IN theOtherData2 INT, IN theStartDate DATE, IN theEndDate DaTE, IN theReferenceDate DaTE) 
    LANGUAGE SQL 
    NOT DETERMINISTIC 
    CONTAINS SQL 
    SQL SECURITY DEFINER 
BEGIN 
declare theNameID int ; 
declare theKeyID int ; 
declare theOtherDataID int default null; 
declare error bool default false; 
declare continue handler for SQLEXCEPTION 
    set error = true; 

    set theKeyID = (select KeyID from map_alias ma where ma.alias = trim(theKey)); 
    set theOtherDataID = (select theOtherDataID from map_otherdata mc where mc.otherdata = trim(theOtherData)); 

    set theNameID = (select max(nameID) from inserttable); 
    set theNameID = theNameID + 1; 
    insert into inserttable values (theNameID , theKeyID , theOtherDataID , theOtherData2, theStartDate , 
    theEndDate , theReferenceDate); 

    if error = true then 
     insert into errors_inserttable values (theNameID , theKeyID , theOtherDataID , theOtherData2, theStartDate , 
    theEndDate , theReferenceDate); 
    end if; 

    set error = false; 
    insert into map_inserttable (theNameID , datasourceid, theName) values (theNameID , 1, theName); 
    if error = true then 
     insert into errors_map_inserttable (theNameID , datasourceid, theName) values (theNameID , 1, theName); 
    end if; 

END 

在Oracle中,我的最後一條語句被忽略(ORA-00922:缺少或無效選項)。它應該是一個局部變量,所以我不確定爲什麼我會得到那個特定的錯誤。

我很努力地宣佈繼續處理程序。我發現了錯誤:

Error(16,27): PLS-00103: Encountered the symbol "FOR" when expecting one of the following:  := . (@ % ; not null range default character. 

這裏是我的預言到目前爲止的代碼:

CREATE OR REPLACE PROCEDURE PROC_ADD_ENTRY 
(
    THENAME IN VARCHAR2 
, THEKEY IN VARCHAR2 
, THEOTHERDATA IN VARCHAR2 
, THEOTHERDATA2 IN NUMBER 
, THEFIRSTDATE IN DATE 
, THELASTDATE IN DATE 
, THEREFERENCEDATE IN DATE 
) AS 
    THENAMEID INT; 
    THEKEYID INT; 
    THEOTHERDATAID int; 
    ERROR bool default false; 
BEGIN 
declare continue HANDLER FOR SQLEXCEPTION set error = true; 



    set THEKEYID = (select KEYID from map_INSERTTABLE mc where mc.Key = trim(THEKEY)); 
END PROC_ADD_ENTRY; 

我敢肯定,這是爲使用Oracle有人太簡單,但我閱讀文檔而且我看到有關在何處以及如何聲明變量,繼續處理程序以及將值分配給變量的衝突信息。 (是:=或=賦值我用這個詞的開頭語句後聲明來聲明變量,或做我做,我在下面顯示的方式?)

如果有人能告訴我:

a),其中,以聲明一個局部變量

b)中如何將一個值到它(即1分配給一個int)

c)中如何從DB的值分配給變量(組VAR =從table_number中選擇數字tn,其中tn.number = 1)

d)如何聲明重新正確的繼續處理程序

我真的很感激它。

回答

3

你已經走向了基本的結構。

create or replace procedure <name> (<param list>) as 
    <local variables> 
begin 
    <body> 
end <name>; 

爲了解決您的具體問題:

a) where to declare a local variable

我標誌着這一節了上面。

b) how to assign a value to it (i.e. 1 to an int)

您將使用:=進行分配。

例如。 thenameid := 1;

要將典型地匹配SQL數據類型(例如NUMBER對於上述)雖然有PL/SQL特定數據類型,如PLS_INTEGER的數據類型。請參閱PL/SQL data types documentation for more details

c) how to assign a value from the DB to a variable (set var = select number from table_number tn where tn.number = 1)

您可以使用into關鍵字與本地定義的變量來存儲值,例如。

l_num_rows number; 
select count(*) into l_num_rows from user_objects; 

d) how to declare a continue handler properly

如果我讀正確理解你的代碼,你想set error = true要執行的每一次出現是一個SQL語句的問題,然後你想存儲的程序進行。

Exception handling是你所追求的。根據需要(例如NO_DATA_FOUND)你想包的任何或您認爲可能有這樣的異常塊錯誤SQL PL/SQL語句,與儘可能多的例外情況:

begin 
    <statements that may fail> 
exception when <exception name> then 
    <action> 
... 
exception when others then 
    <action> 
end; 

「其他」是包羅萬象。您可以處理這個案例,但是與任何錯誤處理一樣,首先要捕獲特定案例是更好的做法。


爲了完成,這裏大概是你的示例程序的樣子。我已經刪除了錯誤代碼標誌,因爲不需要它,也改變了int s到number S:

create or replace procedure proc_add_entry (
    in thename varchar(50), 
    in thekey varchar(50), 
    in theotherdata varchar(50), 
    in theotherdata2 number, 
    in thestartdate date, 
    in theenddate date, 
    in thereferencedate date 
) as 
    thenameid number; 
    thekeyid number; 
    theotherdataid number default null; 
begin 
    begin 
    select keyid into thekeyid from map_alias ma where ma.alias = trim(thekey); 

    select theotherdataid into theotherdataid from map_otherdata mc where mc.otherdata = trim(theotherdata); 

    select max(nameid) into thenameid from inserttable; 
    thenameid := thenameid + 1; 

    insert into inserttable values (thenameid, thekeyid, theotherdataid, theotherdata2, thestartdate, theenddate, thereferencedate); 
    exception when others then 
    insert into errors_inserttable values (thenameid, thekeyid, theotherdataid, theotherdata2, thestartdate, theenddate, thereferencedate); 
    end; 

    begin 
    insert into map_inserttable (thenameid, datasourceid, thename) values (thenameid, 1, thename); 
    exception when others then 
    insert into errors_map_inserttable (thenameid, datasourceid, thename) values (thenameid, 1, thename); 
    end; 

end proc_add_entry;