Không sử dụng CREATE TYPE để trả về kết quả đa hình. Sử dụng và lạm dụng loại GHI để thay thế. Hãy khám phá:
CREATE FUNCTION test_ret(a TEXT, b TEXT) RETURNS RECORD AS $$
DECLARE
ret RECORD;
BEGIN
-- Arbitrary expression to change the first parameter
IF LENGTH(a) < LENGTH(b) THEN
SELECT TRUE, a || b, 'a shorter than b' INTO ret;
ELSE
SELECT FALSE, b || a INTO ret;
END IF;
RETURN ret;
END;$$ LANGUAGE plpgsql;
Hãy chú ý đến thực tế là nó có thể trả về hai tùy chọn hoặc ba tùy thuộc vào đầu vào.
test=> SELECT test_ret('foo','barbaz');
test_ret
----------------------------------
(t,foobarbaz,"a shorter than b")
(1 row)
test=> SELECT test_ret('barbaz','foo');
test_ret
----------------------------------
(f,foobarbaz)
(1 row)
Điều này tàn phá mã, vì vậy hãy sử dụng một số cột nhất quán, nhưng nó rất tiện lợi khi trả về các thông báo lỗi tùy chọn với tham số đầu tiên trả về sự thành công của hoạt động. Được viết lại bằng cách sử dụng một số cột nhất quán:
CREATE FUNCTION test_ret(a TEXT, b TEXT) RETURNS RECORD AS $$
DECLARE
ret RECORD;
BEGIN
-- Note the CASTING being done for the 2nd and 3rd elements of the RECORD
IF LENGTH(a) < LENGTH(b) THEN
ret := (TRUE, (a || b)::TEXT, 'a shorter than b'::TEXT);
ELSE
ret := (FALSE, (b || a)::TEXT, NULL::TEXT);
END IF;
RETURN ret;
END;$$ LANGUAGE plpgsql;
Độ hot gần như hoành tráng:
test=> SELECT test_ret('foobar','bar');
test_ret
----------------
(f,barfoobar,)
(1 row)
test=> SELECT test_ret('foo','barbaz');
test_ret
----------------------------------
(t,foobarbaz,"a shorter than b")
(1 row)
Nhưng làm cách nào để bạn tách nó ra thành nhiều hàng để lớp ORM lựa chọn của bạn có thể chuyển đổi các giá trị sang kiểu dữ liệu gốc của ngôn ngữ bạn chọn? Độ nóng:
test=> SELECT a, b, c FROM test_ret('foo','barbaz') AS (a BOOL, b TEXT, c TEXT);
a | b | c
---+-----------+------------------
t | foobarbaz | a shorter than b
(1 row)
test=> SELECT a, b, c FROM test_ret('foobar','bar') AS (a BOOL, b TEXT, c TEXT);
a | b | c
---+-----------+---
f | barfoobar |
(1 row)
Đây là một trong những tính năng thú vị nhất và ít được sử dụng nhất trong PostgreSQL. Xin hãy phổ biến.