2012-03-01 74 views
4

我的公司正在執行新政策,因爲我的公司會擁有一些國際標準的認證。該政策時,DBA不允許直接查詢到數據庫,如:爲什麼使用存儲過程而不是直接查詢db?

select * from some_table, update some_table, etc. 

我們必須使用存儲過程來完成的查詢。

關於我在這裏的最後一個問題:Postgres pl/pgsql ERROR: column "column_name" does not exist

我想知道,做我們必須爲每個表創建一個存儲過程,或每狀態? 有什麼辦法可以更有效地創建存儲過程嗎?

感謝之前你的答案..

和抱歉,我的英語不好..:d

+0

如果使用存儲過程,連接到數據庫的用戶不需要對基表具有任何直接權限 - 他們只需要能夠執行存儲過程。這可以是一個非常有用的安全措施 – 2012-03-01 09:50:18

+0

是的,我明白,但我們必須創建這麼多的存儲過程,有沒有更有效的方法來做到這一點?也許你可以查看我上面的最後一個問題。如果我必須創建過程,我們如何有效地創建過程? – 2012-03-01 10:01:09

+0

在[相關文章dba.SE](http://dba.stackexchange.com/q/8119/3684)中,您可以找到關於PostgreSQL中存儲過程的性能和特性與原始查詢的大量信息和鏈接。 – 2012-03-08 01:02:36

回答

8

使用存儲過程的一些原因:

  • 他們可能經歷了一些測試,確保他們做的 不允許破壞業務規則,以及一些優化 的性能。
  • 他們確保結果的一致性。每當您被要求執行任務X時,您都會運行與任務X關聯的存儲過程。 如果您編寫查詢,則可能無法每次都以相同方式寫入; 也許有一天,你會忘記一些愚蠢的事情,比如在比較之前強行將文本強制爲 。
  • 他們開始採取稍長不僅僅是一個查詢來寫,但 運行存儲過程花費的時間比寫再次查詢 時間要少。運行足夠多的時間,讓 寫入存儲過程變得更高效。
  • 他們減少或消除需要知道 基礎表的關係。
  • 您可以授予在基礎表上執行存儲過程(與 security definer),但拒絕權限的權限。
  • 程序員(如果你單獨的數據庫管理員和程序員)可以提供 API,而這一切,他們需要知道的。只要您在更改數據庫時維護 API,就可以在不破壞軟件的情況下對基本關係進行必要的更改 ;的確, 你甚至不需要知道他們用你的API做了什麼。

您可能會最終爲每個要執行的查詢創建一個存儲過程。

我不知道爲什麼你認爲這是低效率的,或特別費時相比,只是編寫查詢作爲。如果你只是把查詢放入存儲過程中,額外的工作應該是最小的。

CREATE OR REPLACE FUNCTION aSchema.aProcedure (
    IN var1  text, 
    IN var2  text, 
OUT col1  text, 
OUT col2  text 
) 
    RETURNS setof record 
    LANGUAGE plpgsql 
    VOLATILE 
    CALLED ON NULL INPUT 
    SECURITY DEFINER 
    SET search_path = aSchema, pg_temp 
    AS $body$ 
     BEGIN 
      RETURN QUERY /*the query you would have written anyway*/; 
     END; 
    $body$; 
GRANT EXECUTE ON FUNCTION aSchema.aProcedure(text, text) TO public; 

,正如你在前面的問題時,該功能可以更加動態的通過傳遞列/表作爲參數,並使用EXECUTE(雖然這會增加執行功能的人多少需要了解如何功能作品,所以我儘量避免它)。

如果「效率較低」來自函數中包含的其他邏輯,則與僅使用查詢的比較不公平,因爲該函數正在執行額外的工作。

+0

哇..謝謝你的答案馬特。也許我只是dba世界的初學者。你的回答讓我更加好奇商店中存儲過程的使用。那麼我需要創建什麼樣的存儲過程?在我最後一個問題上,我有程序,是否足夠商業?或者你可以給我更多的技巧來有效地創建過程? – 2012-03-02 10:19:11

+0

這裏是我說效率不高的原因,因爲我必須創建一個一個的程序,就像我的數據庫上的表一樣。例如:查詢表a,我創建過程select_to_a,查詢表b,我創建過程select_to_b。 – 2012-03-02 11:17:36

+0

您可能最終會得到比表更多或更多的過程(表示任務的公共API過程以及作爲以前的助手的私有過程),但不應該有1對1的映射(如果你這樣做的話,你可能會試着寫'SELECT * FROM proc1(),proc2()',這實際上並不是編寫存儲過程的要點,編寫過程總會有開銷,所以它永遠不會更快/更容易/更高效/需要更少的輸入,而不是僅僅寫查詢,我只是認爲開銷是最小的。 – Matt 2012-03-02 13:48:07

相關問題