PL/pgSQL 是 "Procedural Language/PostgreSQL Structured Query Language" 的縮寫
就是指 PostgreSQL 的過程化語言,它是在標準 SQL 的基礎上增加了流程控制、變量聲明和賦值,異常處理等其他編程功能的擴展語言,使得用戶可以編寫更復雜的函數(shù)和存儲過程。
視圖里面不涉及特定的編程語言,所以不需要指定,但是方法和存儲過程需要
CREATE FUNCTION my_function() RETURNS void
LANGUAGE plpgsql
AS $$
BEGIN
-- 函數(shù)體
END;
$$;
CREATE FUNCTION my_function() RETURNS void
AS $$
BEGIN
-- 函數(shù)體
END;
$$
LANGUAGE plpgsql;
$$
$$ 是一種 字符串分隔符,用于包裹函數(shù)的主體內容。它允許你定義多行字符串,并且避免了與 SQL 中的單引號 ' 產(chǎn)生沖突。這樣做的好處是你可以在函數(shù)體中自由使用單引號,而不需要進行轉義。
CREATE FUNCTION get_greeting() RETURNS TEXT
LANGUAGE plpgsql
AS '
BEGIN
RETURN ''Hello, it''s a nice day'';
END;
';
CREATE FUNCTION get_greeting() RETURNS TEXT
LANGUAGE plpgsql
AS $$
BEGIN
RETURN 'Hello, it's a nice day';
END;
$$;
可以在$$中間加入任意字符,表示自定義分隔符,用起來和$$一樣,自定義分隔符可以避免混淆
REATE FUNCTION get_greeting() RETURNS TEXT
LANGUAGE plpgsql
AS $func$
BEGIN
RETURN 'Hello, it's a nice day';
END;
$func$;
變量聲明
可以通過 DECLARE 關鍵字來聲明局部變量。變量的類型可以是 PostgreSQL 支持的任意類型,如 INTEGER、TEXT、NUMERIC、BOOLEAN 等。
DECLARE
my_variable INTEGER := 10; -- 聲明一個整數(shù)變量并初始化
my_text TEXT; -- 聲明一個文本變量
BEGIN
my_text := 'Hello, PL/pgSQL!';
END;
select into
SELECT INTO 語句用于將查詢結果存入變量中。這是在 PL/pgSQL 中常用的語法,目的是將查詢結果賦值給某個變量(即將結果存儲到內存中的一個變量)。這種用法不創(chuàng)建新表,而是用于函數(shù)或存儲過程中處理數(shù)據(jù)。
DECLARE
result INTEGER;
BEGIN
SELECT COUNT(*) INTO result FROM employees;
RAISE NOTICE 'Number of employees: %', result;
END;
而標準SQL里面,也有Select Into ,它用于將查詢結果插入到一個新表中,并且在執(zhí)行查詢時自動創(chuàng)建該新表。
SELECT
employee_id,
employee_name,
department_id,
salary
INTO
temp_employees -- 創(chuàng)建新表 temp_employees 并插入數(shù)據(jù)
FROM
employees
WHERE
salary > 50000;
所以使用時需要注意是在標準SQL里面還是在PL/pgSQL里面
PERFORM 語句
PERFORM 語句用于執(zhí)行不返回結果的查詢(通常是執(zhí)行函數(shù)或者查詢但不關心返回值)。
BEGIN
PERFORM some_function();
END;
動態(tài) SQL (EXECUTE)
EXECUTE 用于執(zhí)行動態(tài) SQL 語句。你可以根據(jù)運行時的需求生成 SQL 查詢,并在 EXECUTE 中執(zhí)行它。
DECLARE
table_name TEXT := 'employees';
sql_query TEXT;
BEGIN
sql_query := 'SELECT * FROM ' || table_name;
EXECUTE sql_query;
END;
記錄與行類型 (RECORD, ROW)
RECORD 是一種動態(tài)類型,可以存儲任意行的查詢結果,而不需要提前知道行的結構。也就是說,RECORD 適用于返回值列數(shù)和類型未知的情況下,特別適合于處理動態(tài)的查詢。只能在 PL/pgSQL 中使用,不能作為函數(shù)的返回類型。
DECLARE
rec RECORD;
BEGIN
FOR rec IN SELECT * FROM employees LOOP
RAISE NOTICE 'Employee: %', rec.name;
END LOOP;
END;
ROW 是 PostgreSQL 中的行類型(composite type),它與表中的一行記錄非常相似。ROW 類型通常需要預定義具體的字段和類型,因此它是一種 靜態(tài)類型。你可以將表的某一行賦值給一個 ROW 類型的變量。
- 需要明確知道行的結構(字段名和類型)。
- 常用于函數(shù)返回特定表的行或者某些字段組合。
- 可以用作函數(shù)的返回值類型。
DECLARE
emp_row employees%ROWTYPE; -- 聲明一個與 employees 表相同結構的行類型
BEGIN
SELECT * INTO emp_row FROM employees WHERE id = 1;
RAISE NOTICE 'Employee ID: %, Name: %', emp_row.id, emp_row.name;
END;
返回多行 (RETURNS SETOF)
SETOF 表示返回一個集合,如果函數(shù)需要返回多個結果行,可以使用 RETURNS SETOF 來定義。SETOF 是set of的意思
CREATE FUNCTION get_employee_names() RETURNS SETOF TEXT
LANGUAGE plpgsql
AS $$
BEGIN
RETURN QUERY SELECT name FROM employees;
END;
$$;
CREATE FUNCTION get_all_employees() RETURNS SETOF employees
LANGUAGE plpgsql
AS $$
BEGIN
RETURN QUERY SELECT * FROM employees;
END;
$$;
SELECT id, name FROM get_all_employees();
數(shù)組
PL/pgSQL 支持數(shù)組的操作,你可以對數(shù)組進行遍歷、添加元素等操作。
DECLARE
my_array INTEGER[] := ARRAY[1, 2, 3, 4, 5];
elem INTEGER;
BEGIN
FOREACH elem IN ARRAY my_array LOOP
RAISE NOTICE 'Element: %', elem;
END LOOP;
END;
return query
-
RETURN QUERY用來返回 多行查詢結果,它允許你返回一個結果集。
CREATE FUNCTION get_high_salary_employees(min_salary NUMERIC) RETURNS SETOF employees
LANGUAGE plpgsql
AS $$
BEGIN
RETURN SELECT * FROM employees WHERE salary > min_salary;
END;
$$;
這個函數(shù)實際上是 錯誤的,因為 PostgreSQL 期望在返回一個查詢結果集時使用 RETURN QUERY。簡單的 RETURN 只能返回單個值或表達式,而不能處理 SQL 查詢結果的返回。
-
RETURN:用于返回單個值或單行,例如在標量函數(shù)中。CREATE FUNCTION get_employee_name(emp_id INT) RETURNS TEXT LANGUAGE plpgsql AS $$ DECLARE emp_name TEXT; BEGIN SELECT employee_name INTO emp_name FROM employees WHERE employee_id = emp_id; RETURN emp_name; -- 單行結果,直接返回 END; $$; ` -
RETURN QUERY:用于返回多行查詢結果(集合),特別是在SETOF函數(shù)中。CREATE FUNCTION get_high_salary_employees(min_salary NUMERIC) RETURNS SETOF employees LANGUAGE plpgsql AS $$ BEGIN RETURN QUERY SELECT * FROM employees WHERE salary > min_salary; -- 返回一個結果集 END; $$;