2012-07-10 50 views
0

我一直在嘗試創建一個腳本來檢測角色是否已經感染,如果它發生了,它應該撤銷所有權限。這工作得很好做這樣的:動態檢測Postgresql中的角色

DO $$DECLARE count int; 
BEGIN 
SELECT count(*) INTO count FROM pg_roles WHERE rolname = 'superman'; 
IF count > 0 THEN 
    REVOKE ALL PRIVILEGES ON TABLE FROM superman; 
END IF; 
END$$; 

但現在我想這是每環境動態的,因爲我會用每環境不同的角色名稱。所以我試圖用\一套機制,但似乎並沒有使用PL/SQL的時候工作,所以,如果我會做類似下面的PostgreSQL是抱怨與語法錯誤:

/set environment _int 

DO $$DECLARE count int; 
BEGIN 
SELECT count(*) INTO count FROM pg_roles WHERE rolname = 'superman'; 
IF count > 0 THEN 
    REVOKE ALL PRIVILEGES ON TABLE FROM superman:environment; 
END IF; 
END$$; 

雖然如果我不會在pl/sql中執行撤銷聲明就可以了。所以我的問題是如何通過傳遞參數使我的腳本動態,以便它們被替換?

回答

1

您必須爲動態SQL使用EXECUTE。另外,DO語句不能帶參數。創建PLPGSQL功能:

CREATE OR REPLACE FUNCTION f_revoke_all_from_role(_role text) 
    RETURNS void AS 
$BODY$ 
BEGIN 

IF EXISTS (SELECT 1 FROM pg_roles WHERE rolname = _role) THEN 
    EXECUTE 'REVOKE ALL PRIVILEGES ON TABLE x FROM ' || quote_ident(_role); 
END IF; 

END; 
$BODY$ LANGUAGE plpgsql; 

電話:

SELECT f_revoke_all_from_role('superman'); 
  • IF塊是EXISTS簡單。

  • 我使用quote_ident()來避免SQLi。

  • 表名可能是函數的第二個參數...

+0

啊確定..日Thnx!我會試試這個。我已經害怕這樣做了。我覺得這很奇怪,但是由於在Oracle中可以將外部變量傳遞給plsql腳本,而無需編寫函數。我只想要這個邏輯,所以我可以部署我的數據庫。爲什麼我必須爲此創建一個函數?沒有其他方式像甲骨文那樣做嗎? – Tranquilized 2012-07-10 22:12:57

+0

@ user1515731:我不知道任何。 plpgsql函數似乎並不複雜,或者它呢? – 2012-07-10 22:17:16

+0

不,它不是真的,但我不喜歡這樣一個事實,即我必須創建一個函數來檢測角色是否存在,並基本上將它放在後面,因爲我不會在我的應用程序中使用它。但我會嘗試thnx爲您的幫助:-) – Tranquilized 2012-07-11 07:56:59