PL/pgSQL

PL/pgSQL 是 "Procedural Language/PostgreSQL Structured Query Language" 的缩写
就是指 PostgreSQL 的过程化语言,它是在标准 SQL 的基础上增加了流程控制、变量声明和赋值,异常处理等其他编程功能的扩展语言,使得用户可以编写更复杂的函数和存储过程。
视图里面不涉及特定的编程语言,所以不需要指定,但是方法和存储过程需要

CREATE FUNCTION my_function() RETURNS void
LANGUAGE plpgsql
AS $$
BEGIN
    -- 函数体
END;
$$;
CREATE FUNCTION my_function() RETURNS void
AS $$
BEGIN
    -- 函数体
END;
$$
LANGUAGE plpgsql;

$$

$$ 是一种 字符串分隔符,用于包裹函数的主体内容。它允许你定义多行字符串,并且避免了与 SQL 中的单引号 ' 产生冲突。这样做的好处是你可以在函数体中自由使用单引号,而不需要进行转义。

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; -- 声明一个整数变量并初始化
    my_text TEXT;              -- 声明一个文本变量
BEGIN
    my_text := 'Hello, PL/pgSQL!';
END;

select into

SELECT INTO 语句用于将查询结果存入变量中。这是在 PL/pgSQL 中常用的语法,目的是将查询结果赋值给某个变量(即将结果存储到内存中的一个变量)。这种用法不创建新表,而是用于函数或存储过程中处理数据。

DECLARE
    result INTEGER;
BEGIN
    SELECT COUNT(*) INTO result FROM employees;
    RAISE NOTICE 'Number of employees: %', result;
END;

而标准SQL里面,也有Select Into ,它用于将查询结果插入到一个新表中,并且在执行查询时自动创建该新表。

SELECT
    employee_id,
    employee_name,
    department_id,
    salary
INTO
    temp_employees  -- 创建新表 temp_employees 并插入数据
FROM
    employees
WHERE
    salary > 50000;

所以使用时需要注意是在标准SQL里面还是在PL/pgSQL里面

PERFORM 语句

PERFORM 语句用于执行不返回结果的查询(通常是执行函数或者查询但不关心返回值)。

BEGIN
    PERFORM some_function();
END;

动态 SQL (EXECUTE)

EXECUTE 用于执行动态 SQL 语句。你可以根据运行时的需求生成 SQL 查询,并在 EXECUTE 中执行它。

DECLARE
    table_name TEXT := 'employees';
    sql_query TEXT;
BEGIN
    sql_query := 'SELECT * FROM ' || table_name;
    EXECUTE sql_query;
END;

记录与行类型 (RECORD, ROW)

RECORD 是一种动态类型,可以存储任意行的查询结果,而不需要提前知道行的结构。也就是说,RECORD 适用于返回值列数和类型未知的情况下,特别适合于处理动态的查询。只能在 PL/pgSQL 中使用,不能作为函数的返回类型。

DECLARE
    rec RECORD;
BEGIN
    FOR rec IN SELECT * FROM employees LOOP
        RAISE NOTICE 'Employee: %', rec.name;
    END LOOP;
END;

ROW 是 PostgreSQL 中的行类型(composite type),它与表中的一行记录非常相似。ROW 类型通常需要预定义具体的字段和类型,因此它是一种 静态类型。你可以将表的某一行赋值给一个 ROW 类型的变量。

  • 需要明确知道行的结构(字段名和类型)。
  • 常用于函数返回特定表的行或者某些字段组合。
  • 可以用作函数的返回值类型。
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 表示返回一个集合,如果函数需要返回多个结果行,可以使用 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();

数组

PL/pgSQL 支持数组的操作,你可以对数组进行遍历、添加元素等操作。
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;
$$;

这个函数实际上是 错误的,因为 PostgreSQL 期望在返回一个查询结果集时使用 RETURN QUERY。简单的 RETURN 只能返回单个值或表达式,而不能处理 SQL 查询结果的返回。

  • RETURN:用于返回单个值单行,例如在标量函数中。

    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 函数中。

    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;
    $$;
    
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,417评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,921评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,850评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,945评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,069评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,188评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,239评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,994评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,409评论 1 304
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,735评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,898评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,578评论 4 336
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,205评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,916评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,156评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,722评论 2 363
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,781评论 2 351

推荐阅读更多精彩内容

  • 一、概述 PL/pgSQL函数在第一次被调用时,其函数内的源代码(文本)将被解析为二进制指令树,但是函数内的表达式...
    GadflyBSD阅读 3,266评论 0 1
  • PostgreSql 的PL/pgSQL 块结构 本文我们学习PL/pgSQL结构块,包括如何写结构块和执行结构块...
    不玩了啊阅读 220评论 0 0
  • 本文由 @小刘先森 原创,转载请注明出处。 PL/pgSQL系列文章,方便小伙伴们学习。 PL/pgSQL从入门到...
    小刘先生阅读 1,381评论 0 0
  • 前言 本文叙述了在Mysql、MSsql、Oracle、PostgreSQL平台下的sql注入探测方式与利用,作为...
    白面安全猿阅读 567评论 0 2
  • sqlmap用户手册 说明:本文为转载,对原文中一些明显的拼写错误进行修正,并标注对自己有用的信息。 ======...
    wind_飘阅读 2,039评论 0 5