bca*_*lla 5 postgresql functions
我编写了这个函数,它应该遍历文本数组并将每个元素(这是一个类型转换的整数)转换为十六进制,附加到文本变量,然后返回十六进制。然而,我什么也得不到。
有没有人看到该函数有任何问题会导致它不返回任何内容?
CREATE OR REPLACE FUNCTION array_convert_to_hex(text[])
RETURNS text
AS
$$
DECLARE
arrInts ALIAS FOR $1;
retVal text;
BEGIN
FOR I IN array_lower(arrInts, 1)..array_upper(arrInts, 1) LOOP
retVal := retVal || lpad(cast(to_hex(arrInts[I]::integer) as varchar), 2, '0');
END LOOP;
RETURN retVal;
END;
$$
LANGUAGE plpgsql
STABLE
RETURNS NULL ON NULL INPUT;
Run Code Online (Sandbox Code Playgroud)
当然,彼得对这个问题的看法是正确的。然而,这整个函数是不必要的缓慢和复杂 - 重复的字符串连接对性能来说是可怕的,无论如何,最好避免 PL/PgSQL 循环。
您可以使用普通 SQL 函数执行相同的工作generate_subscripts:
CREATE OR REPLACE FUNCTION intarr_to_hex_string(integer[]) RETURNS text AS $$
SELECT
string_agg(
lpad(to_hex($1[x]),2,'0'),
''
order by x
)
FROM generate_subscripts($1,1) x;
$$ LANGUAGE sql;
Run Code Online (Sandbox Code Playgroud)
上面的版本需要一个整数数组,但你可以接受带有重载的文本数组:
CREATE OR REPLACE FUNCTION intarr_to_hex_string(text[]) RETURNS text AS $$
SELECT intarr_to_hex_string($1::integer[])
$$ LANGUAGE sql;
Run Code Online (Sandbox Code Playgroud)
请注意,没有进行完整性检查以确保十六进制字符串为两位或更少。您真的应该在使用 CASE 语句执行 PL/PgSQL 函数的地方添加一个检查,如果输入错误,则会引发错误。这是一个完整的例子:
CREATE OR REPLACE FUNCTION raise_exception(text)
RETURNS void LANGUAGE plpgsql AS
$BODY$
BEGIN
RAISE EXCEPTION '%', $1;
END;
$BODY$;
CREATE OR REPLACE FUNCTION intarr_to_hex_string(integer[]) RETURNS text AS $$
SELECT
string_agg(lpad(
CASE WHEN $1[x] < 256 THEN
to_hex($1[x])
ELSE
raise_exception('Argument to intarr_to_hex_string contained value '||coalesce($1[x]::text,'NULL')||', expected all values in i[] to be 0 <= i < 256. Full argument was '||quote_literal($1)||'.')::text
END,
2, '0'),
''
order by x)
FROM generate_subscripts($1,1) x;
$$ LANGUAGE sql;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1195 次 |
| 最近记录: |