2016-04-25 70 views
1

我是繼承了連接到Oracle 11g數據庫的Webforms應用程序的Microsoft堆棧(C#,SQL Server,EF等)的開發人員。該應用程序目前充滿了我想要轉換爲參數化存儲過程的內聯SQL語句。但是,習慣了T-SQL,我發現向PL/SQL轉變的過程相當陡峭。返回數據集的Oracle存儲過程

大多數SQL語句是從基表

select field1, field2, fieldn 
from foo 
where field1 = 'blah' 

返回過濾數據集在T-SQL相當簡單的語句,這將是相當簡單

create procedure fooproc 
    @filter varchar(100) 
as 
begin 
    select field1, field2, field3 
    from foo 
    where field1 = @filter 
end 

不幸的是,這不是」在PL/SQL中似乎很簡單。在搜索,我找到了答案,其中包括:

  1. 使用功能,而不是一個程序(這使我懷疑,如果在SQL Server地圖一到一個程序在Oracle程序)
  2. 創建「包」的程序(還是不太清楚那是什麼)
  3. 使用遊標或循環(這似乎邪惡,只是錯)

此外,大多數例子中,我發現聯機的Oracle存儲過程返回一個標量值或根本沒有值。我認爲這是很多人想要執行的一項相當常見的任務,但是我的google-fu在這個方面一定不是很強大。所以如果有人能幫我翻譯,我會很感激。

感謝

+0

只是好奇,爲什麼你要轉換現有的SQL(這也可能爲甲骨文工作,取決於)存儲過程調用,尤其如果你不舒服的書寫PL/SQL(也有其他原因,直接的SQL會優先於存儲的特效)。 – tbone

+0

有幾個原因。首先,如果格式不正確,內聯sql容易受到sql注入攻擊的影響。我想要做的另一個主要原因是關於分離的問題。我想將我的數據邏輯放在數據庫中,使用專爲sql調試而設計的工具更容易閱讀和調試。 – NevDull

+0

我的問題是因爲你似乎提出的是TAPI設計,這是一個壞主意(而不是從表中選擇x,y,z你必須調用某個函數)。有關TAPI和XAPI的更多討論,請參見[本文](http://stackoverflow.com/questions/3092041/understanding-the-differences-between-table-and-transaction-apis)。另一個有趣的討論(Tom Kyte和Steve Feurstein)是[這裏](https://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:672724700346558185)。這些鏈接中有很多信息!請享用。 – tbone

回答

0

一個SQL Server存儲過程只是返回結果集將最自然地轉化爲一個Oracle存儲函數返回一個指針。像

CREATE OR REPLACE FUNCTION fooFunc(p_field1 IN foo.field1%type) 
    RETURN sys_refcursor 
IS 
    l_rc sys_refcursor; 
BEGIN 
    OPEN l_rc 
    FOR SELECT field1, field2, field3 
     FROM foo 
     WHERE field1 = p_field1; 
    RETURN l_rc; 
END; 

在Oracle 12.1的東西,有一些syntactic sugar for implicit results允許程序隱含返回引用遊標進行從SQL Server的轉換更容易,但你的問題表明你仍然在11g,以致於可能不是一個選項。

您可能還有一個out參數類型爲sys_refcursor的過程。但是,通常情況下,您應該使用函數來僅僅返回修改數據的對象的結果和過程。

通常情況下,所有的Oracle過程和函數都會被封裝到將相關功能的各個位組合在一起的包中。如果你有半打的功能,讓您在使用不同的條件查詢foo,你會希望把所有這些功能在單一封裝中,只是爲了保持組織的事情。

+1

我一直在模糊mssql中的函數和特效之間的界限,因爲函數可以返回標量和表值。我想這也是跨越到oracle的。我會給這個鏡頭。我感到很驚訝,因爲每一位曾經編寫過數據驅動的Web應用程序的.net開發人員都必須編寫CRUD代碼才能與數據庫交談,這是多麼困難。 – NevDull