2017-02-05 63 views
-2

我有一個用PL/Python編寫的函數。它是在Python運行的數據庫功能,這是因爲通過安裝一個程序語言的許可:如何將這個PostgreSQL函數從PL/Py轉換爲PL/SQL?

CREATE PROCEDURAL LANGUAGE 'plpythonu' HANDLER plpython_call_handler 

(我發現了一個很不錯的技巧,允許非管理員用戶權限運行,通過使用一個唯一的名稱,雖然它已經沒有太多與我的問題,我敢肯定你會有些奇怪我是怎麼做這個,所以下面是答案)

CREATE TRUSTED PROCEDURAL LANGUAGE 'plpythonu2' HANDLER plpython_call_handler 
GRANT USAGE ON LANGUAGE plpythonu2 TO admin; 

我們手頭上的問題,我的「黑客「以上對我有用,但如果我想使用Amazon的RDS服務,我不能安裝語言,而PL/Python不可用。 SQL,但是,是。

因此,我需要幫助將用Python編寫的以下函數轉換爲純SQL。

CREATE OR REPLACE FUNCTION "public"."human_readable_bits" (
    "b" bigint = 0 
) 
RETURNS varchar AS 
$body$ 
import math 
if b: 
    exponent = math.floor(math.log(b)/math.log(1024)) 
    val = b/pow(1024, math.floor(exponent)) 
    val = round(val*2)/2 -- This rounds to the nearest HALF (X.5) B, Kb, Mb, Gb, etc. 
    return "%.2f %s" % (val, ('B','Kb','Mb','Gb','Tb','Pb','Eb','Zb','Yb')[int(exponent)]) 
else: 
    return "0 Gb" 
$body$ 
LANGUAGE 'plpythonu2' 
VOLATILE 
RETURNS NULL ON NULL INPUT 
SECURITY INVOKER 
COST 100; 

此功能允許我執行的查詢,如:

=> SELECT human_readable_bits(3285824466906); 
human_readable_bits 
--------------------- 
3.00 Tb 
(1 row) 

OR

=> SELECT human_readable_bits(5920466906); 
human_readable_bits 
--------------------- 
5.50 Gb 
(1 row) 

此外,作爲一個側面說明/次要的問題,之後我創建的函數時,我看DDL,它裏面有一句話說「SECURITY INVOKER」,有人知道這意味着什麼嗎?

+0

第二個查詢將是Mb不是Gb我是對的? –

回答

1

一種純PLPGSQL功能轉換將是:

CREATE OR REPLACE FUNCTION public.human_readable_bits(b NUMERIC) 
    RETURNS VARCHAR AS 
$BODY$ 
declare 
    exponent integer; 
    val float; 
    arr varchar[]; 
    sz VARCHAR(10); 
    result varchar(20); 
BEGIN 
    if b is null or b = 0 then 
     return '0 B'; 
    end if; 

    if b < 1024 then 
     return b::varchar || ' Bits'; 
    end if; 

    arr := ARRAY['B','Kb','Mb','Gb','Tb','Pb','Eb','Zb','Yb']; 
    exponent := floor(log(b)/log(1024)); 
    val := b/power(1024,exponent); 
    val := round(val*2)/2; 

    sz := arr[trunc(floor(log(b)/log(1024)))]; 

    if strpos(val::varchar,'.') > 0 then 
     result := substr(val::varchar, 1, strpos(val::varchar,'.')-1); 
     result := result || '.' || rpad(substr(val::varchar, strpos(val::varchar,'.')+1), 2, '0') || ' ' || sz; 
    else 
     result := val::varchar || '.00 ' || sz; 
    end if; 
    return result; 

END; 
$BODY$ 
    LANGUAGE plpgsql VOLATILE; 

由於此功能的結果是:

select human_readable_bits(328582446690656456434534453) hrb0, 
     human_readable_bits(3285824466906) hrb1, 
     human_readable_bits(5920466906) hrb2, 
     human_readable_bits(1024) hrb3, 
     human_readable_bits(512) hrb4, 
     human_readable_bits(null) hrb5; 

會導致:

hrb0  hrb1  hrb2  hrb3  hrb4  hrb5 
    272.00 Zb 3.00 Gb  5.50 Mb  1.00 B  512 Bits  0 B 

按你的身邊問題的答案可以很容易找到在Create Function Documentation

SECURITY INVOKER指示該功能是與調用它的用戶的權限來執行。這是默認設置。 SECURITY DEFINER指定該功能將以創建它的用戶的特權執行。