我有一个用PL / Python编写的函数。它是一个在Python中运行的数据库函数,由于通过以下方式安装了过程语言,因此允许使用它。
CREATE PROCEDURAL LANGUAGE 'plpythonu' HANDLER plpython_call_handler
(我发现了一个很好的技巧,允许非管理员用户使用一个独特的名称来运行,虽然它与我的问题没什么关系,我相信你们中的一些人会想知道我在做什么这个,所以下面是答案)
CREATE TRUSTED PROCEDURAL LANGUAGE 'plpythonu2' HANDLER plpython_call_handler
GRANT USAGE ON LANGUAGE plpythonu2 TO admin;
现在对于手头的问题,上面的“黑客”对我有用,但如果我想使用亚马逊的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”,是否有人知道这意味着什么?< / p>
答案 0 :(得分: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指定该函数将使用创建它的用户的权限执行。