參數數據類型
更新時間 2025-02-05 09:36:45
最近更新時間: 2025-02-05 09:36:45
分享文章
本頁介紹天翼云TeleDB數據庫PL/pgsql函數的參數數據類型。
數據類型(可以有模式修飾),可以是基本類型,復合類型、域類型、游標、或者可以引用一個現有表類型、字段類型(建立時轉換為對應的類型)、還可以是多態類型 anyelement、anyarray,也可以是各種數據類型的數組形式。
基本類型
teledb=# CREATE OR REPLACE FUNCTION f3 (a_int integer,a_str text) RETURNS VOID AS
teledb-# $$
teledb$# BEGIN
teledb$# RAISE NOTICE 'a_int = % ; a_str = %',a_int,a_str;
teledb$# END;
teledb$# $$
teledb-# LANGUAGE PLPGSQL;
CREATE FUNCTION
teledb=# SELECT * FROM f3(1,'teledb');
NOTICE: a_int = 1 ; a_str = teledb
f3
----
(1 row)
teledb=# CREATE OR REPLACE FUNCTION f3 (a_int integer[],a_str text[]) RETURNS VOID AS
teledb-# $$
teledb$# BEGIN
teledb$# RAISE NOTICE 'a_int = % ; a_str = %',a_int,a_str;
teledb$# END;
teledb$# $$
teledb-# LANGUAGE PLPGSQL;
CREATE FUNCTION
teledb=# SELECT f3(ARRAY[1,2,3],ARRAY['teledb','pgxz']);
NOTICE: a_int = {1,2,3} ; a_str = {teledb,pgxz}
f3
----
(1 row)
復合類型
teledb=# CREATE TYPE t_per AS
teledb-# (
teledb(# id integer,
teledb(# mc text
teledb(# );
CREATE TYPE
teledb=# CREATE OR REPLACE FUNCTION f3 (a_row public.t_per) RETURNS VOID AS
teledb-# $$
teledb$# BEGIN
teledb$# RAISE NOTICE 'id = % ; mc = %',a_row.id,a_row.mc;
teledb$# END;
teledb$# $$
teledb-# LANGUAGE PLPGSQL;
CREATE FUNCTION
teledb=# SELECT f3(ROW(1,'teledb')::public.t_per);
NOTICE: id = 1 ; mc = teledb
f3
----
(1 row)
teledb=# CREATE OR REPLACE FUNCTION f3 (a_rec public.t_per[]) RETURNS VOID AS
teledb-# $$
teledb$# BEGIN
teledb$# RAISE NOTICE 'a_rec = %',a_rec;
teledb$# RAISE NOTICE 'a_rec[1].id = %',a_rec[1].id;
teledb$# END;
teledb$# $$
teledb-# LANGUAGE PLPGSQL;
CREATE FUNCTION
teledb=# SELECT f3(ARRAY[ROW(1,'teledb'),ROW(1,'pgxz')]::public.t_per[]);
NOTICE: a_rec = {"(1,teledb)","(1,pgxz)"}
NOTICE: a_rec[1].id = 1
f3
----
(1 row)
行類型
teledb=# \d t
Table "public.t"
Column | Type | Collation | Nullable | Default
--------+-------------------+-----------+----------+---------
id | integer | | not null |
mc | character varying | | |
teledb=# CREATE OR REPLACE FUNCTION f3 (a_row public.t) RETURNS VOID AS
teledb-# $$
teledb$# BEGIN
teledb$# RAISE NOTICE 'id = % ; mc = %',a_row.id,a_row.mc;
teledb$# END;
teledb$# $$
teledb-# LANGUAGE PLPGSQL;
CREATE FUNCTION
teledb=# SELECT f3(ROW(1,'teledb')::public.t);
NOTICE: id = 1 ; mc = teledb
f3
----
(1 row)
teledb=> CREATE OR REPLACE FUNCTION f3 (a_rec public.t[]) RETURNS int AS
teledb-> $$
teledb$> BEGIN
teledb$> return a_rec[1].id;
teledb$> END;
teledb$> $$
teledb-> LANGUAGE PLPGSQL;
CREATE FUNCTION
teledb=> SELECT f3(array[row(1,'teledb'),row(2,'pgxz')]::public.t[]);
f3
----
1
(1 row)
teledb=> SELECT f3(array[t.*,t.*]::public.t[]) FROM t LIMIT 2;
f3
----
1
2
域類型
teledb=# CREATE DOMAIN xb AS TEXT CHECK
teledb-# (
teledb(# VALUE = '男'
teledb(# OR VALUE ='女'
teledb(# OR VALUE = ''
teledb(# );
CREATE DOMAIN
teledb=# CREATE OR REPLACE FUNCTION f4 (a_xb public.xb) RETURNS VOID AS
teledb-# $$
teledb$# BEGIN
teledb$# RAISE NOTICE 'a_xb = %',a_xb;
teledb$# END;
teledb$# $$
teledb-# LANGUAGE PLPGSQL;
CREATE FUNCTION
teledb=# SELECT * FROM f4('男');
NOTICE: a_xb = 男
f4
----
(1 row)
teledb=# SELECT * FROM f4('她');
ERROR: value for domain xb violates check constraint "xb_check"
域類型輸入參數值時會檢查是否違反規則。
游標類型
teledb=# CREATE OR REPLACE FUNCTION f5 (a_ref refcursor) RETURNS void AS
teledb-# $$
teledb$# DECLARE
teledb$# v_rec record;
teledb$# BEGIN
teledb$# OPEN a_ref FOR SELECT * FROM t LIMIT 1;
teledb$# FETCH a_ref INTO v_rec;
teledb$# RAISE NOTICE 'v_rec = % ',v_rec;
teledb$# END;
teledb$# $$
teledb-# LANGUAGE PLPGSQL;
CREATE FUNCTION
teledb=# SELECT * FROM f5('a');
NOTICE: v_rec = (1,teledb)
f5
----
(1 row)
teledb=# CREATE OR REPLACE FUNCTION f6 (a_ref refcursor) RETURNS refcursor AS
teledb-# $$
teledb$# BEGIN
teledb$# OPEN a_ref FOR SELECT * FROM t LIMIT 1;
teledb$# RETURN a_ref;
teledb$# END;
teledb$# $$
teledb-# LANGUAGE PLPGSQL;
CREATE FUNCTION
-- 這里需要開啟一個事務
teledb=# BEGIN;
BEGIN
teledb=# SELECT * FROM F6('a');
f6
----
a
多態類型
teledb=# CREATE OR REPLACE FUNCTION f_any(a_arg anyelement) RETURNS VOID AS
$$
BEGIN
RAISE NOTICE '%',a_arg;
END;
$$
LANGUAGE PLPGSQL;
CREATE FUNCTION
teledb=# SELECT f_any(1::integer);
NOTICE: 1
f_any
-------
(1 row)
teledb=# SELECT f_any('teledb'::TEXT);
NOTICE: teledb
f_any
-------
(1 row)
teledb=# SELECT f_any(ROW(1,'teledb')::public.t_per);
NOTICE: (1,teledb)
f_any
-------
(1 row)
teledb=# SELECT f_any(ARRAY[1,2]::INTEGER[]);
NOTICE: {1,2}
f_any
-------
(1 row)
teledb=# SELECT f_any(ARRAY[[1,2],[3,4],[5,6]]::INTEGER[][][]);
NOTICE: {{1,2},{3,4},{5,6}}
f_any
-------
(1 row)
注意多態類型參數函數調用時最好直接聲明參數類型,否則有可能出錯。
teledb=# CREATE OR REPLACE FUNCTION f_any(a_arg anyarray) RETURNS VOID AS
$$
BEGIN
RAISE NOTICE '%',a_arg;
END;
$$
LANGUAGE PLPGSQL;
CREATE FUNCTION
teledb=# SELECT f_any(ARRAY['teledb','pgxz']::TEXT[]);
ERROR: function f_any(text[]) is not unique
LINE 1: SELECT f_any(ARRAY['teledb','pgxz']::TEXT[]);
^
HINT: Could not choose a best candidate function. You might need to add explicit type casts.
Anyelement參數如果寫成數組,其意義就跟anyarray參數一致,所以f_any(a_arg anyelement)與f_any(a_arg anyarray)在調用f_any(ARRAY[1,2])時就會出現函數不是唯一化的錯誤(ERROR: ?function f_any(…) is not unique)提示。
參數默認值
PL/pgsql擴展語言函數支持給參數設置默認值。
teledb=# CREATE OR REPLACE FUNCTION f7 (a_int INTEGER DEFAULT 1) RETURNS VOID AS
teledb-# $$
teledb$# BEGIN
teledb$# RAISE NOTICE 'a_int = %',a_int;
teledb$# END;
teledb$# $$
teledb-# LANGUAGE PLPGSQL;
CREATE FUNCTION
teledb=# SELECT * FROM f7();
NOTICE: a_int = 1
f7
----
(1 row)
備注:如果原來存在一個f7() 這樣的函數,則上面的執行就會出錯,因為系統無法清楚到要執行那個函數,如下所示。
teledb=# CREATE OR REPLACE FUNCTION f7() RETURNS void AS
teledb-# $$
teledb$# BEGIN
teledb$# RAISE NOTICE '無參數';
teledb$# END;
teledb$# $$
teledb-# LANGUAGE plpgsql ;
CREATE FUNCTION
teledb=# SELECT * FROM f7();
ERROR: function f7() is not unique
LINE 1: SELECT * FROM f7();
^
HINT: Could not choose a best candidate function. You might need to add explicit type casts.
出錯提示,f7()函數不是唯一的,這是使用上一個需要特別注意的地方。