sql
  • oracle
  • stored-procedures
  • oracle-sqldeveloper
  • 2012-05-07 58 views 0 likes 
    0

    我正在使用SQL Oracle構建存儲過程。我試圖建立以下Oracle SQL Developer中的存儲過程

    SELECT "Merch"."Id", "Order"."Id", "Order"."OrderExt" 
    FROM "Order" 
    Join "Merch" ON "Order"."MerchId" = "Merch"."Id" 
    WHERE "Merch"."Id" = 25 AND "Order"."OrderExt" = 'TC10045604' 
    

    我想用2個inparameters比較「Merch.Id」和「Order.OrderExt」的SQL查詢的存儲過程。我真的很熟悉SQL-Oracle,並且很難弄清楚如何編寫這個過程。

    我遇到的一個問題是如何返回一個帶有「Merch」的表。「Id」,「Order」,「Id」,「Order」,「OrderExt」?

    我是否以某種方式使用遊標?

    有人可以幫我解決這個問題嗎?

    回答

    4

    你可以寫一個存儲過程,有這是一個SYS_REFCURSOR

    CREATE OR REPLACE PROCEDURE return_cursor(p_merch_id IN "Merch"."Id"%type, 
                  p_order_ext IN "Order"."OrderExt"%type, 
                  p_rc  OUT sys_refcursor) 
    AS 
    BEGIN 
        OPEN p_rc 
        FOR SELECT "Merch"."Id", "Order"."Id", "Order"."OrderExt" 
         FROM "Order" 
           Join "Merch" ON "Order"."MerchId" = "Merch"."Id" 
         WHERE "Merch"."Id" = p_merch_id 
          AND "Order"."OrderExt" = p_order_ext; 
    END; 
    

    這將是更自然的OUT參數,然而,有一個返回SYS_REFCURSOR

    CREATE OR REPLACE FUNCTION return_cursor(p_merch_id IN "Merch"."Id"%type, 
                  p_order_ext IN "Order"."OrderExt"%type) 
        RETURN sys_refcursor 
    AS 
        l_rc sys_refcursor; 
    BEGIN 
        OPEN l_rc 
        FOR SELECT "Merch"."Id", "Order"."Id", "Order"."OrderExt" 
         FROM "Order" 
           Join "Merch" ON "Order"."MerchId" = "Merch"."Id" 
         WHERE "Merch"."Id" = p_merch_id 
          AND "Order"."OrderExt" = p_order_ext; 
        RETURN l_rc; 
    END; 
    

    作爲存儲功能一般的風格問題,具有區分大小寫的表格和列名是非常非常非常好的主意。如果表名與Oracle保留字如Order相匹配,則更不可能是個好主意。強迫每個開發人員總是在每個標識符周圍使用雙引號,並且總是在正確的情況下指定它們會導致比僅僅使用默認的不區分大小寫的約定和避免保留字更多的錯誤。

    2

    就像你說的,你需要使用2個參數,這樣你才能通過Merch.IdOrder.OrderExt過濾數據。

    你可以使用SYS_REFCURSOR返回的結果,例如:

    PROCEDURE MY_PROC 
           (pOrderExt "Order"."OrderExt"%type, 
            pMerchId "Merch"."Id"%type,    
            recordSet OUT SYS_REFCURSOR) 
         AS  
         BEGIN  
         OPEN recordSet FOR 
          SELECT "Merch"."Id", "Order"."Id", "Order"."OrderExt" 
          FROM "Order" 
          INNER JOIN "Merch" ON "Order"."MerchId" = "Merch"."Id" 
          WHERE "Merch"."Id" = pMerchId AND "Order"."OrderExt" = pOrderExt;  
        END MY_PROC; 
    

    這就是你看到的結果(確保你看看輸出變量選項卡中的SQL開發):

    DECLARE 
        pOrderExt "Order"."OrderExt"%type; 
        pMerchId "Merch"."Id"%type;   
        recordSet OUT SYS_REFCURSOR; 
    BEGIN 
        pMerchId := 25 ; 
        pOrderExt := 'TC10045604'; 
    
        MY_PROC (
        pMerchId => pMerchId, 
        pOrderExt => pOrderExt,  
        recordSet => recordSet 
    ); 
        :recordSet := recordSet; --<-- Cursor 
    END; 
    

    編輯:增加了執行示例,並對Justin Cave指出的進行了改進

    +0

    如果SQL語句user473104運行,則需要所有雙引號 - 「Merch」似乎是區分大小寫的標識符。如果'Merch'傳入'varchar2',那麼'Id''是'number'也可能導致問題 - 你最好使用''Merch'。「Id」%type'' –

    +0

    我完全同意使用「Merch」。「Id」%類型。你能否詳細說一下雙引號?我不明白他爲什麼需要他的案件。 – Ulises

    +0

    如果用雙引號將標識符括起來,Oracle會將其解釋爲區分大小寫的標識符。這意味着它只會匹配也使用區分大小寫的標識符創建的對象,並且僅當數據字典中的對象名稱的大小寫與雙引號中的對象名稱的大小相匹配時。如果原始SQL語句正常工作,則表示「Merch」表被創建爲「CREATE TABLE」Merch「...」,並且每個對「Merch」的引用都必須包含雙引號,並且必須區分大小寫 –

    相關問題