我正在使用PostgreSQL 9.3,使用plpgsql
函数:
CREATE TEMP TABLE uuid_inside (
id uuid PRIMARY KEY
);
CREATE FUNCTION uuid_test_func(id uuid)
RETURNS uuid_inside AS
$$
DECLARE
res_uuid_inside uuid_inside;
BEGIN
IF (id = '00000000-0000-0000-0000-000000000001'::uuid) THEN
SELECT uuid_test_func('00000000-0000-0000-0000-000000000000'::uuid)
INTO res_uuid_inside;
RETURN res_uuid_inside;
END IF;
res_uuid_inside.id := id;
RETURN res_uuid_inside;
END;
$$
LANGUAGE plpgsql;
呼叫:
SELECT uuid_test_func('00000000-0000-0000-0000-000000000001'::uuid);
消息:
错误:uuid的输入语法无效:"(00000000-0000-0000-0000-000000000000)"
SQL状态:22P02
但这很好用:
SELECT uuid_test_func('00000000-0000-0000-0000-000000000002'::uuid);
问题不在于递归函数调用 - 原始代码是指内部的其他函数。
答案 0 :(得分:1)
你的函数中的递归似乎毫无意义。这个简单的sql函数完成了这项工作(没有嵌套,没有复合类型包装器):
CREATE FUNCTION uuid_test_func(id uuid)
RETURNS uuid AS
$func$
SELECT CASE WHEN $1 = '00000000-0000-0000-0000-000000000001'::uuid
THEN '00000000-0000-0000-0000-000000000000'::uuid
ELSE $1
END
$func$ LANGUAGE plpgsql;
但这可能只是因为演示的简化。
至于错误消息。您正在遇到PL / pgSQL令人困惑的“功能”:
复合类型分配需要每个类型列一列。将复合类型作为一个整体分配不是一种选择。
这与UUID
类型本身无关。
此修改版本可以使用:
CREATE OR REPLACE FUNCTION uuid_test_func(id uuid)
RETURNS uuid_inside AS
$func$
DECLARE
res_uuid_inside uuid_inside;
BEGIN
IF (id = '00000000-0000-0000-0000-000000000001'::uuid) THEN
SELECT * FROM uuid_test_func('00000000-0000-0000-0000-000000000000'::uuid)
INTO res_uuid_inside.id;
-- INTO res_uuid_inside; -- would work, too - 1st col is assigned
RETURN res_uuid_inside;
END IF;
res_uuid_inside.id := id;
RETURN res_uuid_inside;
END
$func$ LANGUAGE plpgsql;
密切相关的问题:
Passing array of a composite type to stored procedure
那就是说,我建议使用这种简化形式(保持递归和复合结果):
CREATE OR REPLACE FUNCTION uuid_test_func(id uuid)
RETURNS uuid_inside AS
$func$
BEGIN
IF (id = '00000000-0000-0000-0000-000000000001'::uuid) THEN
RETURN (SELECT f FROM uuid_test_func('00000000-0000-0000-0000-000000000000'::uuid) f);
ELSE
RETURN row(id)::uuid_inside;
END IF;
END
$func$ LANGUAGE plpgsql;