基于开发者空间GaussDB云数据库的PLpgSQL实践一

1 概述

1.1 案例介绍

PL/pgSQL是一种程序语言,叫做过程化SQL语言(Procedural Language/Postgres SQL),pl/pgsql是PostgreSQL数据库对SQL语句的扩展。在普通SQL语句的使用上增加了编译语言的特点,所以pl/pgsql就是把数据操作和查询语句组织在pl/pgsql代码的过程性单元中,通过逻辑判断、循环等操作实现复杂的功能或者计算的程序语言。

通过实际操作,让大家深入了解如何利用 PL/pgSQL 开发并部署一个函数功能模块。在这个过程中,大家将学习到从函数创建、数据批量读取到SQL程序编写以及与触发器集成等一系列关键步骤,从而掌握 PL/pgSQL 的基本使用方法,体验其在应用开发中的优势。

1.2 适用对象

  • 企业
  • 个人开发者
  • 高校学生

1.3 案例时间

本案例总时长预计60分钟。

1.4 案例流程

说明:

  1. 领取空间开发桌面;
  2. 在空间开发桌面终端进入GaussDB;
  3. 进行数据库的开发者空间进行GaussDB之PL/pgSQL的操作;

1.5 资源总览

资源名称规格单价(元)时长(分钟)
开发者空间-GaussDB鲲鹏通用计算增强型 kc1 | 2vCPUs | 4G | HCE2.0免费60

最新案例动态,请查阅 《基于开发者空间GaussDB云数据库的PLpgSQL实践一》。小伙伴快来领取华为开发者空间,进入云主机桌面版实操吧!

2 Gauss数据库PL/pgSQL实践

2.1 领取开发者空间GaussDB数据库

免费领取GaussDB在线试用版(2025年 06月 21日 - 2025年 12月 31日)。地址如下:
https://developer.huaweicloud.com/signup/75dae31d0eb04cdcab822c76d35eb9a1
有1000个名额,数量有限,速度为王。

领取后,按提示即可创建数据库,如下:

登录数据库

输入创建数据库时的密码,点击测试连接,通过后点击登录

创建测试数据库,点击确定

查看数据库兼容类型

执行sql:

3 PL/PGSQL实践

PLPGSQL是数据库的编程语言。相当于在数据库中用SQL语言进行逻辑处理与代码开发。可以把业务系统中封装的功能模块下沉到数据库端实现,以达到减轻业务系统的逻辑压力、降低架构复杂度和简化业务系统实现难度。

PLPGSQL是一种块结构型语言,例如匿名块,存储过程和函数体的完整文本必须是块。块定义如下:

[ <<标签>> ]
[ 声明
变量;
变量 := 赋值 ]
BEGIN
    SQL QUERY
END [ 标签];

PLPGSQL定义的功能模块(存储过程和函数)可以互相嵌套。例如SQL块中嵌套子SQL块,存储过程引用PLPGSQL定义的其他函数和模块功能。

3.1 变量赋值与引用

3.1.1 变更声明与赋值

SQL块中所使用的所有变量都必须在plpgsql定义body的开头,用关键字 DECLARE 声明。

变量声明的语法

name [ CONSTANT ] type [ COLLATE collation_name ] [ NOT NULL ] [ { DEFAULT | := | = } expression ];

例如:

DECLARE
var1 TEXT;
var2 INTEGER := 10;
url VARCHAR;
quantity NUMERIC(5);
myrow tablename%ROWTYPE;
myfield tablename.columnname%TYPE;
arow RECORD;
CURSOR c1 IN SELECT col1, col2 FROM table_name WHER 谓词过滤条件;

以上的示例为声明块(DECLARE), := 为PL/SQL中的等号赋值。

DECLARE
quantity integer DEFAULT 32;
url varchar := 'http://mysite.com';
transaction_time CONSTANT timestamp with time zone := now();
tax := subtotal * 0.06;
my_record.user_id := 20;
my_array[j] := 20;
my_array[1:3] := array[1,2,3];
complex_array[n].realpart = 12.3;

变量一旦声明,变量的值就可以在同一SQL块中后续初始化表达式中被使用,例如:

DECLARE
  x integer := 1;
  y integer := x + 1;
3.1.2 变量声明之Function Parameters

引用变量不需要声明,变量引用主要用于函数参数引用。传递给函数的参数使用标识符 $1、$2 等命名,也可以为 $n 参数名声明别名,以增加可读性。然后,可以使用别名或数字标识符来引用参数值。

有两种方法可以创建别名。首选的方法是在 CREATE FUNCTION 命令中为参数指定一个名称,例如:

CREATE FUNCTION sales_tax(subtotal real) RETURNS real AS $$
BEGIN
    RETURN subtotal * 0.06;
END;
$$ LANGUAGE plpgsql;

另一种方法是显式声明别名,使用声明语法

name ALIAS FOR $n;

此样式中的相同示例如下所示:

DROP FUNCTION IF EXISTS sales_tax();
CREATE OR REPLACE FUNCTION sales_tax(real) RETURNS real AS $$
DECLARE
    subtotal ALIAS FOR $1;
BEGIN
    RETURN subtotal * 0.06;
END;
$$ LANGUAGE plpgsql;

注解:

下面两个用例不完全等价。在第一个用例情况下,参数可以引用为 int_t.sales_tax,但在第二个用例下,它不能引用(除非在内部块附加一个标签,参数可以使用该标签来替代)。

下面用例参数int_t的类型sometablename是当前表的表名。由于该函数中使用了表字段的f1,f3,f5,f7四列,所以这块根据实际引用表结构而对应的改变引用字段名。

CREATE TABLE test(f1 int, f3 int, f5 int, f7 int);
CREATE FUNCTION concat_selected_fields(in_t test) RETURNS text AS $$
BEGIN
    RETURN in_t.f1 || in_t.f3 || in_t.f5 || in_t.f7;
END;
$$ LANGUAGE plpgsql;
CREATE FUNCTION instr(varchar, integer) RETURNS integer AS $$
DECLARE
    v_string ALIAS FOR $1;
    index ALIAS FOR $2;
BEGIN
    -- some computations using v_string and index here
END;
$$ LANGUAGE plpgsql;

注意:如果提示instr函数创建失败,是因为在public模式下,会与系统函数instr重名,所以最好是在用户同名模式下创建,例如用户myuser在库下应该会对应有myuser模式

当使用输出参数声明PL/PGSQL函数时,与正常输入参数相同的方式为输出参数提供 $n 名称和可选别名。输出参数实际上是一个以NULL开关的变量;它应该在函数执行期间赋值。参数的最终值是返回值。例如上面的第一个示例也可以用下面的方式实现。

CREATE OR REPLACE FUNCTION sales_tax(subtotal real, OUT tax real) AS $$
BEGIN
    tax := subtotal * 0.06;
END;
$$ LANGUAGE plpgsql;

创建函数前确保该函数不存在,否则同schema下同名函数冲突。

注意:此处省略了返回值 RETURN real 。

要调用具有OUT参数的函数,在函数调用中省略输出参数(s)。

SELECT sales_tax(100.00);

在返回多个值时,输出参数非常有用。如下:

CREATE FUNCTION sum_n_product(x int, y int, OUT sum int, OUT prod int) AS $$
BEGIN
    sum := x + y;
    prod := x * y;
END;
$$ LANGUAGE plpgsql;

SELECT * FROM sum_n_product(2, 4);

这种写法有效地创建了函数结果的匿名记录类型。如果给出 RETURN 子句,则必须是RETURN RECORD。

如果把上面的函数 sum_n_product 改写成存储过程,如下:

DROP FUNCTION sum_n_product;
CREATE PROCEDURE sum_n_product(x int, y int, OUT sum int, OUT prod int) AS 
BEGIN
    sum := x + y;
    prod := x * y;
END;

在对存储过程的调用中,必须指定所有参数。对于输出参数,从普通SQL调用过程时可以指定NULL:

CALL sum_n_product(2, 4, NULL, NULL);

截图运行结果:

但是,当从PL/PGSQL调用存储过程时,应该为任何输出参数编写一个变量;该变量将接收调用的结果。PL/PGSQL函数的另一种方法是声明返回类型 RETURNS TABLE。例如:

CREATE FUNCTION extended_sales(p_itemno int)
RETURNS TABLE(quantity int, total numeric) AS $$
BEGIN
    RETURN QUERY SELECT s.quantity, s.quantity * s.price FROM sales AS s
                 WHERE s.itemno = p_itemno;
END;
$$ LANGUAGE plpgsql;

该方式完全等价于声明一个或多个OUT参数并指定 RETURNS SETOF 类型。

当PL/PGSQL函数的返回类型声明为多态类型时将创建一个特殊参数 $0 。它的数据类型根据实际输入类型推断出函数的返回类型。$0 被初始化为NULL,并且可以被函数修改,因此它也可以用来保存返回值。$0 也可作别名。例如下面函数适用于 + 运算符的任何数据类型:

CREATE FUNCTION add_three_values(v1 anyelement, v2 anyelement, v3 anyelement)
RETURNS anyelement AS $$
DECLARE
    result ALIAS FOR $0;
BEGIN
    result := v1 + v2 + v3;
    RETURN result;
END;
$$ LANGUAGE plpgsql;

通过将一个或多个输出参数声明为多态类型,可以获得相同的效果。在该情况下,不使用特殊的 $0 参数,输出参数本身具备相同的结果,例如:

DROP FUNCTION IF EXISTS add_three_values;
CREATE FUNCTION add_three_values(v1 anyelement, v2 anyelement, v3 anyelement, OUT sum anyelement)
AS $$
BEGIN
    sum := v1 + v2 + v3;
END;
$$ LANGUAGE plpgsql;

anycompatible是PostgreSQL特性,GaussDB暂时没有移植该功能。故下面anycompatible类型只了解即可。

在实践中,声明多态函数中使用任何兼容的数据类型会非常有效,以便自动将输入参数提升为一个常见的公共类型。例如:

CREATE FUNCTION add_three_values(v1 anycompatible, v2 anycompatible, v3 anycompatible)
RETURNS anycompatible AS $$
BEGIN
    RETURN v1 + v2 + v3;
END;
$$ LANGUAGE plpgsql;

上面用例引用方法如下:

SELECT add_three_values(1, 2, 4.7);

该函数调用,会自动将参数值1, 2从integer整型转换成numeric小数型。

注:多态类型有11种,anyelement只是其中一个,该内容属于数据类型。由于数据类型较为简单不做过多说明,读者自学数据类型。

3.1.3 变量声明之ALIAS

该内容主要用于触发器的实现。因为触发器有涉及到Update和Delete等DML。而数据的Update和Delete会涉及到新元组(new tuple)和旧元组(old tuple)。比如Delete的谓词条件Where语句中column = old.tuple。

语法如下:

newname ALIAS FOR oldname;

例如:

DECLARE
  prior ALIAS FOR old;
  updated ALIAS FOR new;

注意:由于ALIAS创建了两种不同的方式来命名同一个对象,因此不受限制的使用可能会引起困惑。最好仅用于覆盖预定名称。

3.1.4 变量声明之Copying Types

语法如下:

name table.column%TYPE
name variable%TYPE

%TYPE提供表字段或者先前声明PL/PGSQL变量的数据类型,可以声明在数据库中已经存在的变量类型。例如:

变量与数据库中表 users 的字段 user_id 是相同的数据类型,则PL/PGSQL在声明variable时,可以用如下写法:

declare
  variable users.user_id%TYPE;

还可以在%TYPE之后写入数组修饰,创建一个保存引用类型的数组变量:

declare
  variables users.user_id%TYPE[];
  variables users.user_id%TYPE ARRAY[4];  -- equivalent to the above

正如在声明表字段为数组时,无论编写多个括号还是特定的数组维度并不重要:GaussDB将给定元素类型的所有数组为相同类型,而不考虑维度。

重点

通过使用**%TYPE**,不需要知道被引用的结构中的数据类型。如果被引用项的数据类型在将来发生变化(例如:将user_id的类型从整数更改为实数),也不需要改变函数定义。

%TYPE 在多态函数中特别有用,因为内部变量所需的数据类型在一次调用到下一次调用时可能发生变化。可以通过将**%TYPE**应用于函数的参数或结果占位符来创建适当的变量。

表结构中使用数组类型时,则方法如下(其写法不同于PL/PGSQL变量声明):

CREATE TABLE sal_emp (
    name            text,
    pay_by_quarter  integer[],
    schedule        text[][]
);
CREATE TABLE tictactoe (
    pay_by_quarter integer ARRAY,
    sales integer ARRAY[4],
    squares integer[3][3]
);

读者自学数组类型的字段写入,数组访问,此处不作过度讲解,自行学习。

3.1.5 变量声明之Row Types

语法如下

name table_name%ROWTYPE;
name composite_type_name;

复合类型的变量被称为行变量或者行类型变量。只要 SELECT 或 FOR 查询的列集合与变量声明的类型相匹配中,则该变量就能存储该查询的整行结果集(元组Tuple)。通常使用小数点表示访问元组的各个字段(例如:rowvar.field)。

使用 table_name%ROWTYPE 表示将 ROWTYPE 类型的变量声明为现有表或视图的行具有相同的类型,也可通过给出复合类型的类型名来声明 ROWTYPE 变量。由于每个表关系都有一个同名的关联复合类型,因此在 GaussDB 中,是否写 %ROWTYPE 其实不重要。但是使用 %ROWTYPE 的表关系更具有可移植性。

%ROWTYPE 与 %TYPE 一样,后面可以跟数组修饰符来声明一个变量,该变量保存引用复合类型的数组。

函数的参数可以定义成复合类型(表完整的行)。在该情况下,对应的标识符 $n 将是行变量,可以从中选择字段,例如 $1.usr_id 。

复合类型的示例如下所示:Table1 和 Table2 是至少具有上述字段的现有表:

3.1.6 变量声明之Record Types

语法如下:

name RECORD;

Record 变量类似于RowType变量,但其没有预定义结构。在 SELECT 或 FOR 操作期间分配的实际的Row结构就是Record变量的结构类型。所以每次在变量赋值时,变量的子结构都会发生变化。所以在变量被第一次赋值之前,它没有子结构,并且任何访问该变量的字段都将导致运行时报错。

注意:RECORD类型变量并不是一个实际的数据类型,只是占位符。当PL/PGSQL函数的返回类型被声明为RECORD时,它与RECORD变量的概念并不完全一样,即便该函数可能使用RECORD变量来保存其返回结果集。在这两种情况下,编写自定义函数时,实际的ROW结构是未知的,但是对于返回RECORD的函数,实际的结构是在解析调用查询时确定的,而RECORD变量可以动态地更改其行结构。

3.1.7 PL/PGSQL中变量的比较运算操作

该部分内容比较简单不做详细讲解,理解如下用例:

CREATE FUNCTION less_than(a text, b text) RETURNS boolean AS $$
BEGIN
    RETURN a < b;
END;
$$ LANGUAGE plpgsql;
SELECT less_than(f1, f3) FROM test;
CREATE FUNCTION less_than_1 (a text, b text) RETURNS boolean AS $$
DECLARE
    local_a text := a;
    local_b text := b;
BEGIN
    RETURN local_a < local_b;
END;
$$ LANGUAGE plpgsql;
CREATE FUNCTION less_than_c(a text, b text) RETURNS boolean AS $$
BEGIN
    RETURN a < b COLLATE "C";
END;
$$ LANGUAGE plpgsql;
3.1.8 变量引用之循环变量迭代
  • For Loop中迭代的循环整数变量。
  • 迭代游标结果数据集的循环变量。

后续循环控制和游标章节会展示具体用法,此处不做过多详解。

3.2 条件控制

PL/pgSQL有两种条件控制语句:IF语句和CASE语句。

其中IF语句有3种形式:

IF ... THEN ... END IF
IF ... THEN ... ELSE ... END IF
IF ... THEN ... ELSIF ... THEN ... ELSE ... END IF

CASE语句有2种形式:

CASE ... WHEN ... THEN ... ELSE ... END CASE
CASE WHEN ... THEN ... ELSE ... END CASE
3.2.1 IF-THEN

语法如下:

IF boolean-expression THEN
    statements
END IF;

例如:(下面SQL需要在存储过程/函数中套用)

IF v_user_id <> 0 THEN
    UPDATE users SET email = v_email WHERE user_id = v_user_id;
END IF;
3.2.2 IF-THEN-ELSE

语法如下:

IF boolean-expression THEN
    statements
ELSE
    statements
END IF;

用法如下:(下面SQL需要在存储过程/函数中套用)

IF parentid IS NULL OR parentid = ''
THEN
    RETURN fullname;
ELSE
    RETURN hp_true_filename(parentid) || '/' || fullname;
END IF;

IF v_count > 0 THEN
    INSERT INTO users_count (count) VALUES (v_count);
    RETURN 't';
ELSE
    RETURN 'f';
END IF;
3.2.3 IF-THEN-ELSIF

语法如下:

IF boolean-expression THEN
    statements
[ ELSIF boolean-expression THEN
    statements
[ ELSIF boolean-expression THEN
    statements
    ... ]
] 
[ ELSE
    statements ]
END IF;

例如:(下面SQL需要在存储过程/函数中套用)

IF number = 0 THEN
    result := 'zero';
ELSIF number > 0 THEN
    result := 'positive';
ELSIF number < 0 THEN
    result := 'negative';
ELSE
    -- hmm, the only other possibility is that number is null
    result := 'NULL';
END IF;

IF demo_row.sex = 'm' THEN
    pretty_sex := 'man';
ELSE
    IF demo_row.sex = 'f' THEN
        pretty_sex := 'woman';
    END IF;
END IF;
3.2.4 CASE search-expression WHEN

语法如下:

CASE search-expression
    WHEN expression [, expression [ ... ]] THEN
      statements
  [ WHEN expression [, expression [ ... ]] THEN
      statements
    ... ]
  [ ELSE
      statements ]
END CASE;

该语法功能与C语言的SWITCH CASE类似。(下面SQL需要在存储过程/函数中套用)

CASE x
    WHEN 1, 2 THEN
        msg := 'one or two';
    ELSE
        msg := 'other value than one or two';
END CASE;

SELECT * INTO myrec FROM emp WHERE empname = myname;
IF NOT FOUND THEN
    RAISE EXCEPTION 'employee % not found', myname;
END IF;

BEGIN
    SELECT * INTO STRICT myrec FROM emp WHERE empname = myname;
    EXCEPTION
        WHEN NO_DATA_FOUND THEN
            RAISE EXCEPTION 'employee % not found', myname;
        WHEN TOO_MANY_ROWS THEN
            RAISE EXCEPTION 'employee % not unique', myname;
END;
3.2.5 Searched CASE

语法如下:

CASE
    WHEN boolean-expression THEN
      statements
  [ WHEN boolean-expression THEN
      statements
    ... ]
  [ ELSE
      statements ]
END CASE;

用例如下:(下面SQL需要在存储过程/函数中套用)

CASE
    WHEN x BETWEEN 0 AND 10 THEN
        msg := 'value is between zero and ten';
    WHEN x BETWEEN 11 AND 20 THEN
        msg := 'value is between eleven and twenty';
END CASE;

该形式的CASE语句和IF-THEN ELSEIF类似等价。

注:条件控制语句都是结合存储过程PROCEDURE和自定义函数FUNCTION,在SQL体中套用的。

3.3 循环控制

PL/pgSQL在执行一些重复的SQL语句时,一般用循环结构实现,PL/pgSQL包含的循环语法有LOOP, EXIT, CONTINUE, WHILE, FOR, FOREACH。

3.3.1 LOOP

语法如下:

[ <<label>> ]
LOOP
    statements
END LOOP [ label ];

LOOP语句定义了一个无条件循环,该循环将无限期地重复,直到由EXIT或RETURN语句终止。可选Label由嵌套循环中的EXIT和CONTINUE语句使用,以指定该语句的引用哪个循环。

3.3.2 EXIT

语法如下:

EXIT [ label ] [ WHEN boolean-expression ];

EXIT后面若没有跟Label,内部循环到END LOOP则结束退出。如果EXIT有Label,则该标签是当前循环体或者外层嵌套循环体的标签。在循环体的END处结束或者控制SQL块。

若指定WHEN,则当 boolean-expression 为True时,才会退出循环。否则控制流程将运行SQL体退出后的语句。该语法用于所有类型的循环体,并不限制于无条件循环体。

当有BEGIN语句开始SQL块时,EXIT将跳到BEGIN开启的SQL块之后继续执行。

例如:(下面SQL需要在存储过程/函数中套用)

LOOP
    -- some computations
    IF count > 0 THEN
        EXIT;  -- exit loop
    END IF;
END LOOP;

LOOP
    -- some computations
    EXIT WHEN count > 0;  -- same result as previous example
END LOOP;

<<ablock>>
BEGIN
    -- some computations
    IF stocks > 100000 THEN
        EXIT ablock;  -- causes exit from the BEGIN block
    END IF;
    -- computations here will be skipped when stocks > 100000
END;
3.3.3 CONTINUE

语句:

CONTINUE [ label ] [ WHEN boolean-expression ];

如果CONTINUE语句不带Label标签,则SQL自动从循环体的下一次循环开始位置执行,即跳过循环体中剩余的SQL语句。如果CONTINUE语句带Label标签,则执行循环体中标签指示的位置。

若指定了关键字WHEN,并且boolean-expression为true时,才会执行下一次循环的迭代。如果boolean-expression为false,则执行流传递给CONTINUE后面的SQL。

CONTINUE语句能和所有类型的循环体一起使用;它不限于和无条件循环体。

示例如下:(下面SQL需要在存储过程/函数中套用)

LOOP
    -- some computations
    EXIT WHEN count > 100;
    CONTINUE WHEN count < 50;
    -- some computations for count IN [50 .. 100]
END LOOP;
3.3.4 WHILE循环

语法如下:

[ <<label>> ]
WHILE boolean-expression LOOP
    statements
END LOOP [ label ];

当 boolean-expression 为True时,则进行WHILE的SQL循环体执行statement。每次循环执行SQL时,都会判断 boolean-expression 。(下面SQL需要在存储过程/函数中套用)

WHILE amount_owed > 0 AND gift_certificate_balance > 0 LOOP
    -- some computations here
END LOOP;

WHILE NOT done LOOP
    -- some computations here
END LOOP;
3.3.5 FOR循环

语法如下:

[ <<label>> ]
FOR name IN [ REVERSE ] expression .. expression [ BY expression ] LOOP
    statements
END LOOP [ label ];

FOR循环 IN 后面的 expression 表达式是一个整数值范围上迭代。变量名自动定义来整数类型,该变量生命周期只存在于内循环。在变量的起始值和结束值每次进入循环体时计数一次。如果未指定 BY 关键字,则迭代为1,否则为BY子句中指定的值。如果REVERSE关键字被指定,则表示FOR循环的迭代变量是从大到小遍历,每次循环迭代变量减少。

FOR循环体的几种示例写法如下:

-- 迭代变量i增序遍历,从1到10,增量默认为1
FOR i IN 1..10 LOOP
    -- i will take on the values 1,2,3,4,5,6,7,8,9,10 within the loop
END LOOP;
-- 迭代变量i降序遍历(REVERSE),从10到1,降量默认为1
FOR i IN REVERSE 10..1 LOOP
    -- i will take on the values 10,9,8,7,6,5,4,3,2,1 within the loop
END LOOP;
-- 迭代变量i降序遍历(REVERSE),从10到1,降量默认为2(BY 2)
FOR i IN REVERSE 10..1 BY 2 LOOP
    -- i will take on the values 10,8,6,4,2 within the loop
END LOOP;

注:

如果FOR循环的迭代变量i在增序遍历中,起始值比结束值大,则循环体SQL不会被执行,也不会报错。反之降序遍历同理。

3.3.6 Query Results作变循环迭代变量

用不同的FOR循环体语句,可以迭代SQL查询结果集,并做对应的操作。语法如下:

[ <<label>> ]
FOR target IN query LOOP
    statements
END LOOP [ label ];

target可以是 record 变量,row 变量或者是逗号分隔的标题列表。依次为查询的每一行结果集分配给迭代变量,在循环体中被引用。

示例如下:

CREATE FUNCTION refresh_mviews() RETURNS integer AS $$
DECLARE
    mviews RECORD;
BEGIN
    RAISE NOTICE 'Refreshing all materialized views...';
    FOR mviews IN
       SELECT n.nspname AS mv_schema,
              c.relname AS mv_name,
              pg_catalog.pg_get_userbyid(c.relowner) AS owner
         FROM pg_catalog.pg_class c
    LEFT JOIN pg_catalog.pg_namespace n ON (n.oid = c.relnamespace)
        WHERE c.relkind = 'm'
     ORDER BY 1
    LOOP

        -- Now "mviews" has one record with information about the materialized view

        RAISE NOTICE 'Refreshing materialized view %.% (owner: %)...',
                     quote_ident(mviews.mv_schema),
                     quote_ident(mviews.mv_name),
                     quote_ident(mviews.owner);
        EXECUTE format('REFRESH MATERIALIZED VIEW %I.%I', mviews.mv_schema, mviews.mv_name);
    END LOOP;

    RAISE NOTICE 'Done refreshing materialized views.';
    RETURN 1;
END;
$$ LANGUAGE plpgsql;

如果该循环体通过 EXIT 关键字退出,则在循环体退出后依然可以访问 Row 变量的数据。

FOR-IN-EXECUTE语句是ROW变量迭代的另一个语法

[ <<label>> ]
FOR target IN EXECUTE text_expression [ USING expression [, ... ] ] LOOP
    statements
END LOOP [ label ];

与上面的结构类似,不同的是Query查询结果集被作为字符串表达式处理,在FOR循环的SQL对其进行评估和重规划,可以像普通SQL一样使用预处理的SQL查询和灵活的动态SQL,参数值可以使用USING插入动态SQL。

Query查询结果集的处理的另一种方案是使用游标。

3.3.7 数组的LOOP循环体结构

FOREACH 循环体和 FOR 循环体比较类似,其用于替代SQL查询结果集迭代变量的语法,其迭代变量是一个数组变量。语法如下:

[ <<label>> ]
FOREACH target [ SLICE number ] IN ARRAY expression LOOP
    statements
END LOOP [ label ];

如果没有SLICE关键字,或者SLICE被指定为0,则通过计算表达式生成的数组里各个数值遍历循环体SQL,循环体将分配访问序列中每个变量的值。示例如下:

CREATE FUNCTION sum_a (int[]) RETURNS int8 AS $$
DECLARE
  s int8 := 0;
  x int;
BEGIN
  FOREACH x IN ARRAY $1
  LOOP
    s := s + x;
  END LOOP;
  RETURN s;
END;
$$ LANGUAGE plpgsql;

无论是多维数组,数据都是按存储顺序访问。虽然target只是一个变量,在遍历复合类型数组时,target则表示复合变量的数组列表。当SLICE值为正时,FOREACH遍历数组的SLICE不再是单个值,SLICE值则是一个不超过数组维度的整数常量。target变量是一个数组值,其接收遍历数组数据里每个SLICE,数组的维度用SLICE来指定。

下面用例通过一维数组SLICE迭代变量展示其用法。

CREATE FUNCTION scan_rows(int[]) RETURNS void AS $$
DECLARE
  x int[];
BEGIN
  FOREACH x SLICE 1 IN ARRAY $1
  LOOP
    RAISE NOTICE 'row = %', x;
  END LOOP;
END;
$$ LANGUAGE plpgsql;

SELECT scan_rows(ARRAY[[1,2,3],[4,5,6],[7,8,9],[10,11,12]]);
3.3.8 ERROR抓取

默认情况下,PL/pgSQL函数中发生的任何错误都会中止该函数和周围事务的执行。通过使用带有EXCEPTION子句的BEGIN块来捕获错误并从中恢复。该语法是START语法的常规扩展:

[ <<label>> ]
[ DECLARE
    declarations ]
BEGIN
    statements
EXCEPTION
    WHEN condition [ OR condition ... ] THEN
        handler_statements
    [ WHEN condition [ OR condition ... ] THEN
          handler_statements
      ... ]
END;

当没有错误输出时,该语法会执行所有的SQL语句,SQL控制流传递给END关键字后的下一个SQL语句。但如果在语句中发生错误,则放弃对SQL的进一步处理,并将SQL控制流传递给异常列表,该列表用于搜索与发生错误第一个匹配的信息。如果找到匹配信息,则执行相应的 handler_statements ,然后将SQL控制流传递给END关键字后的下一个SQL语句。如果列表中没有匹配到发生错误的内容,刚该 ERROR 会通过 EXCEPTION 终止对该函数的处理。

该 condition 名字可能是任意一个错误码,如同类别的名称可以匹配类型中的任何错误。特殊condition的名称 OTHERS 匹配除QUERY_CANCELED和ASSERT_FAILURE之外的所有错误类型。condition 名称不区分大小写。另外错误条件可以由SQLSTATE代码指定。例如下面示例,其是等价的。

WHEN division_by_zero THEN ...
WHEN SQLSTATE '22012' THEN ...

当错误被 EXCEPTION 子句捕获时,PL/pgSQL函数的局部变量被保存,但SQL块中对数据库持久状态的所有更改都将回滚。下面示例作为参考:

INSERT INTO mytab(firstname, lastname) VALUES('Tom', 'Jones');
BEGIN
    UPDATE mytab SET firstname = 'Joe' WHERE lastname = 'Jones';
    x := x + 1;
    y := x / 0;
EXCEPTION
    WHEN division_by_zero THEN
        RAISE NOTICE 'caught division_by_zero';
        RETURN x;
END;

当控制流到达分配的y时,则会输出 division_by_zero分支要输出的错误信息。该数据会被EXCEPTION 子句捕获,RETURN 语句中返回的x的增量值,但 UPDATE 命令的效果则被回滚。但SQL体之前的 INSERT 不被回滚。因此数据库的最终结果是包含 Tom Jones 的数据,而不是包含 Joe Jones 的内容。

注:与不包含SQL子句块相比,包含子句块的进入和退出成本要高的多。因此,除非必要时才使用。

3.3.9 从ERROR中获取信息

在PL/pgSQL中,关于当前 exception 有两种方法获取 error message。指定特殊变量和 GET STACKED DIAGNOSTICS 语法关键字。

在一个 exception 处理句柄中,指定特殊变量 SQLSTATE 包含了引发异常对应的错误码。特殊变量 SQLERRM 包含与异常相关的错误信息。这些变量在 EXCEPTION 结构外是没有被定义的。

在异常处理 SQL 程序中,也可用 GET STACKED DIAGNOSTICS 关键字来检索当前有关的异常消息。命令格式如下:

GET STACKED DIAGNOSTICS variable { = | := } item [ , ... ];

每个关键字都具备指定变量的状态值。当前可用状态值如下表所示:

名称类型描述
RETURNED_SQLSTATEtextexception的SQLSTATE错误 码
COLUMN_NAMEtextexception相关的字段名
CONSTRAINT_NAMEtextexception相关的约束名
PG_DATATYPE_NAMEtextexception相关的数据类型名
MESSAGE_TEXTtextexception的主要消息文本
TABLE_NAMEtextexception相关的表名
SCHEMA_NAMEtextexception相关的模式名
PG_EXCEPTION_DETAILtextexception的详细信息,前提是该message存在
PG_EXCEPTION_HINTtextexception提示消息的文本内容,前提是message存在
PG_EXCEPTION_CONTEXTtextexception的堆栈文本信息

如果 EXCEPTION 没有设置变量值,则返回一个空字符串。例如:

DECLARE
  text_var1 text;
  text_var2 text;
  text_var3 text;
BEGIN
  -- some processing which might cause an exception
  ...
EXCEPTION WHEN OTHERS THEN
  GET STACKED DIAGNOSTICS text_var1 = MESSAGE_TEXT,
                          text_var2 = PG_EXCEPTION_DETAIL,
                          text_var3 = PG_EXCEPTION_HINT;
END;

该部分具体的示例,见GaussDB官方网站用例,此处不再详述。

GET DIAGNOSTICS语句

3.4 NULL语句

在PL/pgSQL中,NULL占位符是非常有用的。例如 NULL 以指示 if/then/else 链的一个分支故意为空。故此用NULL语句。

例如下面两个匿名块是等价的

BEGIN
    y := x / 0;
EXCEPTION
    WHEN division_by_zero THEN
        NULL;  -- ignore the error
END;

注:在Oracle的PL/SQL中,不允许使用空语句列表,因此在这种情况下需要使用NULL语句。但PL/pgSQL中允许什么都不写来替代NULL语句。但目前GaussDB不支持什么都不写的场景,故还是要用NULL语法。

3.5 匿名块和存储过程实现

匿名块是oracle中PLSQL的内容,GaussDB上不确定具有该功能,故此处暂时不做说明。

存储过程是PL/pgSQL的重要功能,其主要目的是把一连串SQL操作进行封装成一个功能模块,用户使用该一组SQL模块时,只需要调用该存储过程的名称即可执行一连串封装的SQL操作。存储过程里的SQL实现对于用户是黑盒。即用户不知道调用的存储过程其中具体的实现过程。存储过程与自定义函数最大的区别是,存储过程没有返回值,函数必须要有RETURN。但是存储过程也可以输出内容和结果,比较调用oracle的兼容包dbe_output.print_line中的输出函数,或者用RAISE输出内容,还有用Output参数来存储要输出的结果。

存储过程可带参数也可以不带参数。如下示例:(其中table需要替换成存在的表名,xxx是查询的where条件,根据具体情况自行修改,也可以省略where条件)

create or replace procedure cursor_function() as 
declare
	var1 int;
	var2 int;
	cursor c1 for select va1, va2 from table where xxx;
begin 
	open c1;
	loop fetch c1 into var1, var2;
	exit when c1%notfound;
		body;
		raise notice 'xx%, xx%',var1,var2;
	end loop;
	close c1;
end;
/

编写存储过程,输入个数,生成student,id从100000开始,starttime是当前时间。示例如下:

create table student (id int,vdate timestamp);
create or replace procedure ins_student(num int)
as 
declare
    id int:= 100000;
    var int;
    jishu int;
begin
    for var in 1 .. num loop
        insert into student values (id, now());
        id := id + 1;
    end loop;
    select count(*) into jishu from student;
    raise info '已插入%行, 目前student表共有%行', num, jishu;
end;
/

结束游标的存储过程相结合使用,示例如下:

create table sjh_cursor (a int,b int,c int);
insert into sjh_cursor values(1,2,3);
insert into sjh_cursor values(4,5,6);
--创建游标,使用游标从表里查询并输出2字段
create or replace procedure pro_sjh() as
declare
    cursor c1 is select a, b from sjh_cursor;
    var1 int;
    var2 int;
begin
    open c1;
    loop fetch c1 into var1, var2;
        exit when c1%notfound;
        raise notice 'sjh_cursor表a列数据为: %, b列数据为: %', var1, var2;
     end loop;
     close c1;
end;
/
call pro_sjh();

编写存储过程, 输入学号和科目名称, 返回对应的平均成绩,示例如下:

create or replace procedure avg_score(id int,coursename varchar(20) ,avgscore out int)
as
begin
case when coursename='math' then 
select avg(math) into avgscore from student where student_id=id;
when coursename='pysical' then 
select avg(pysical) into avgscore from student where student_id=id;
when coursename='music' then 
select avg(music) into avgscore from student where student_id=id;
when coursename='art' then 
select avg(art) into avgscore from student where student_id=id;
end case;
end;
/

PL/PGSQL更多知识请移步基于开发者空间Gauss数据库的PLPGSQL实践二了解学习。

4 反馈改进建议

如您在案例实操过程中遇到问题或有改进建议,可以到论坛帖评论区反馈即可,我们会及时响应处理,谢谢!

相关推荐

鸿蒙案例上新啦 | 购物、听歌、健身:15个模板带你一键激活社交娱乐

页面层级如何组织、跨页共享状态如何同步、列表与详情及个人中心如何形成稳定闭环。鸿蒙开发实践中心将这些高频消费与互动场景沉淀为可参考的标准模板,提供从业务架构到界面实现的快捷实践入口。更多实战案例欢迎前往鸿蒙开发实践中心案例中心查看并开启云端体验。

华为云官方博客 338

鸿蒙案例上新啦 | 出门打车、到家上课:25个模板带你一屏打通日常生活

如何合理拆分页面组件、如何建立单一可信的状态源、如何让用户在每一步操作中都获得明确反馈。鸿蒙开发实践中心以标准化的应用与元服务模板为入口,将清晰的业务架构与可复用的代码结构直观呈现。不妨立即挑选一个感兴趣的方向进入云端环境,从页面布局、组件封装、状态管理到路由组织,亲手跑通你的鸿蒙实战项目。

华为云官方博客 325

LakeAgent:DWS数据仓库的第二大脑,告别 “翻译式运维”,迈入智能自治时代

和普通 SQL 改写工具不同,LakeAgent 自动做多方案代价对比,主动规避负优化陷阱:补充分区键过滤实现剪枝,扫描分区由 37 收敛至 1,执行代价从 758.28 降至 113.74;未来的数据仓库,将不止能算、能存,更能看懂自己、诊断自己、理解自己。长久以来,数仓的智能都依附于人:信号需要人解读,瓶颈需要人研判,经验困在个体里,无法随底座永续生长。CPU 高、CPU 告警、CPU 诊断、CPU 使用率过高、CPU 满。语法、错误码、计费、性能调优、最佳实践、故障处置等全场景内容。

华为云官方博客 555

如何使用RDS Supabase后端BaaS能力:文件存储(File Storage)

• product-images(公开桶,允许公共读取):策略名称"Public read for product-images",允许SELECT,目标角色anon,策略定义bucket_id = 'product-images'。上传/删除需另配INSERT/DELETE策略,详见SQL。• product-specs(私有桶,仅认证用户访问自己的文件夹):建议拆为上传、读取、删除三条策略,策略定义均为 bucket_id = 'product-specs' 且仅限本人文件夹(详见下文 SQL)。

华为云官方博客 476

如何使用RDS Supabase后端BaaS能力:实时订阅与推送(Realtime)

Realtime 把数据库的每次变更同步到客户端:表里增、删、改一行,订阅者无需刷新页面或主动请求即可秒级收到。三大能力各司其职:• Postgres Changes — 监听表的 INSERT/UPDATE/DELETE,变化即通知• Broadcast — 客户端之间直接互发,适合瞬时通知、协同编辑• Presence — 跟踪频道里“谁在线”典型场景有实时数据展示(订单、库存、监控指标即时刷新)、即时通讯(消息收发、在线名单、“对方正在输入”)、协同编辑与实时通知。

华为云官方博客 465

AI Agent如何通过MCP连接到华为云RDS Supabase应用平台

Schema元数据列出所有可访问的表(按schema分组)。Schema元数据列出表的列及元数据(类型/默认值/约束)。Schema元数据列出所有约束(PK/FK/UNIQUE/CHECK/EXCLUDE)。可按schema/表/类型过滤。Schema元数据列出所有外键关系。可按schema/表过滤。Schema元数据列出所有索引及定义和大小。可按schema/表过滤。Schema元数据列出已应用的数据库迁移记录。Schema元数据列出已安装的PostgreSQL扩展。

华为云官方博客 473

华为大数据Flink让每一 CU 算力,跑出开源 5.74 倍的性能

1. 开源Apache Flink 已成为业界流计算事实标准,但在极端重负载场景下存在性能瓶颈。2. 华为大数据Flink通过多项自研深度优化,在执行计划、算子执行、状态存储三个层面构建协同的优化体系。3. Nexmark Benchmark 测试结果:整体性能提升 5.74 倍,极端重负载场景性能领先最高 18.3 倍。4. 100% 兼容 Apache Flink 1.20,业务代码零改造,无缝迁移。

华为云官方博客 380

LakeAgent实战 | 业务分析篇从一句提问到业务分析

本文以“订单金额变化”分析为例,展示LakeAgent如何通过自然语言提问,结合DataArtsStudio的数据资产与专业技能,帮助业务人员快速定位数据、生成SQL、追踪血缘、生成报告。从问题出发,逐步实现数据发现、变化洞察、原因追溯与团队协作,最终形成可复用的分析流程与企业规则,显著提升数据分析效率与一致性。

华为云官方博客 389

华为云RDS Supabase AI应用已开放公测 :30分钟搭建AI应用后端

认证、存储、实时推送、数据库API——4个后端模块,传统开发需要数周。今天,你只需要30分钟。AI创业公司的全栈开发工程师。上周老板说"下周要上线的AI对话应用,后端你来搞"——认证鉴权、数据库接口、文件存储、实时推送,每一个模块都需要数周搭建,而市场不会等你。小张打开华为云RDS Supabase,30分钟搭好认证、数据库API、对象存储,剩下的时间全用来打磨AI交互体验。基于开源Supabase+华为云RDS PostgreSQL全托管能力,为开发者提供。

华为云官方博客 396

如何使用RDS Supabase后端BaaS能力:数据库函数(Database Function)

上一篇介绍了 Database Data API——建表即自动生成增删改查接口,解决单表读写,但聚合统计、跨表事务、字段自动维护等逻辑已超出其能力边界。本篇推进到数据库函数(Database Function):把业务逻辑封装进数据库,前端通过 .rpc() 调用,由触发器自动响应数据变更。上一篇中,小张基于 Data API 完成了产品目录的建表与基础读写。但新需求随之而来:按分类统计产品数与价格区间、上架新品同时写产品表与定价表、产品修改后自动刷新更新时间。

华为云官方博客 464

如何使用RDS Supabase后端BaaS能力:创表即生成API(Database Data API)

认证、存储、实时推送、数据库API——4个后端模块,传统开发要数周。本系列逐个拆解,首篇聚焦数据库API(Database Data API):建表即得 API,无需手写后端。小张,AI创业公司的全栈工程师。老板让他做个产品目录页,展示产品与价格、支持上下架。传统做法要搭后端、写接口、配权限,工期少说1-2周;而在华为云RDS Supabase,建两张表、应用 SDK 直连,几分钟增删改查全跑通。

华为云官方博客 478

从一句话到一个能出去的链接,AI开发者空间做了什么

自行搭建的 Agent、正在使用的开源项目、团队既有的工具,都可以接入,可以通过AI创建或者手动搭建环境;华为云 AI开发者空间——面向开发者的云端一站式开发平台,做的就是把这段路接上:环境免安装,浏览器打开即为完整的 Linux 运行环境,预置的 AI 智能体开箱即用。第一个任务建议选能出结果的:做一个游戏、生成一个页面、创建一台实例,从需求走到可访问的链接,一次就能看清这个环境在做什么。沙箱是一个完整的 Linux 环境,依赖、服务、端口都是真实的,不是模拟。环境释放后,权限随之失效。

华为云官方博客 426

华为云码道配置自定义大模型,四种方式完整实操

案例介绍。

华为云官方博客 624

图数据库:实现穿透式监管的数据基座

穿透式监管标志着国企监管从“管企业”向“管资本”转型过程中的关键一跃。而图数据库正是这一跃的技术支点。从股权穿透到资金链穿透,从供应链穿透到数据穿透,华为GES图数据库正在将“穿透式监管”从理念变为可落地、可操作的实践。无论是天眼查式的全量链路查询,还是某集团财经的税务规则判断,抑或是芯片供应链式的部件风险分析,乃至通过Palantir构建决策知识图谱,其底层逻辑都是一致的——用图的力量,穿透一切形式的“隔离层”,直抵风险本质与责任核心。

华为云官方博客 664

《公共云三十问》正式收官,奔赴企业AI百场景新征程

今年6月底,公共云产业联盟重点推出《公共云三十问》专栏,以每周三问的节奏,连载十周,解读《先进公共云》白皮书,分享国计民生系列案例,旨在凝聚共识、推动落地实践。同时,专栏分析公共云在产业升级、民生福祉、科技创新、全球发展等方面的作用,梳理中国特色公共云发展路径:以普惠云拓展用云广度,以智算云提升用云深度,以自主云夯实用云厚度,以全球云打开用云跨度。这十问从专属云、行业云切入,深入政务、金融、交通、电力、钢铁、化工、油气、制造等国计民生场景,回答公共云“怎么用”。

华为云官方博客 473

开发者小技巧|IAM配置,让码道代码智能体连续30天免登录

案例介绍。

华为云官方博客 645

码道深度对接CodeArts,让需求自动落地为代码

案例介绍。

华为云官方博客 720

【公共云三十问 之三十】拥抱AI,企业如何建设面向智能体的专属云?

企业可分阶段建设覆盖开发、运行、运营及安全的一体化智能体平台——从构建一站式、高低码协同的智能体开发平台,到打造高性能、极致弹性的运行时环境,再到搭建AgentOps驱动的持续运营与运维体系,同时构建端到端、多层次的全链路安全防护体系。在数据湖建设方面,遵循“存量复用、平滑演进、AI导向、分步迭代”原则,分三阶段推进——打造AI多模数据湖核心能力、完成存算分离与统一元数据管理、实现闭环赋能全面支撑智能体规模化落地,在保护既有投资的前提下将传统数据平台转型为AI数据专属供给平台。

华为云官方博客 823

【公共云三十问 之二十九】国计民生之制造:制造云如何重塑数智时代的新质生产力?

平台打通软件交付的完整路径,覆盖需求管理、代码托管、代码检查、编译构建、制品仓库、部署、测试等关键环节,支持大模型能力融入研发全流程,实现从需求到交付的端到端管理。通过构建“研发一朵云”,方案打破地域与组织壁垒,实现跨团队协同开发,有效缩短软件交付周期,助力工业制造企业从“传统研发”走向“敏捷研发”,加速数智化转型进程。当制造云真正成为数据流通的平台、AI创新的底座,公共云的社会价值将从基础设施层向生产场景层持续延伸,为新型工业化建设和制造强国战略注入源源不断的动力,重塑数智时代的中国制造新质生产力。

华为云官方博客 789

告别重复手工迁仓,码道MCP+Skill实现仓库批量迁移

案例介绍。

华为云官方博客 790

【公共云三十问 之二十八】国计民生之油气:智算云如何叩响数智时代的“地心蓝金”?

西南油气田以“向地球深部要资源”为战略方向,联合以华为云Stack为代表的公共云服务商共同打造统一算力底座,建设西南区域数据湖与通用技术平台,构建“勘探开发工程技术、天然气生产过程管控、天然气产运储销”等三个一体化协同应用场景,支撑油气勘探、开发生产、管输储运等全业务链的数智化转型。当智算云真正成为数据流通的平台、AI创新的底座,油气田得以将算力效能、数据价值与智能技术深度融入勘探开发全链条,将“看不见的算力”转化为“摸得着的储量”,以智能化手段持续降低勘探风险、缩短发现周期、提高采收效率,确保生产安全。

华为云官方博客 613

【公共云三十问 之二十七】国计民生之化工:数智云如何重塑传统化工新范式?

在架构方面,方案构建云边协同的统一体系,涵盖AI协同、数据协同与运营协同三大维度——总部集中训练大模型,边缘节点负责推理执行,云边持续迭代,实现“边用边学”的智能闭环,模型平均精度提升20%以上。此外,方案提供一站式企业级工业物联网平台、数据湖与数据治理平台,覆盖工业数据分析“采、存、算、管、用”全流程,打通生产现场与管理系统间的数据壁垒,有效消除数据孤岛。层面,方案充分发挥软硬协同优势,实现计算、存储、网络与云平台的深度协同,训练线性度超95%,为大模型训练推理提供强劲算力支撑。▲化工“数智”新模式。

华为云官方博客 663

【公共云三十问 之二十六】国计民生之钢铁:数智云如何淬炼中国钢铁新力量?

同时,构建云边端协同的统一架构,支撑集团总部与各生产基地两级协同发展——总部集中训练大模型,边缘节点负责推理执行,云边持续迭代,实现训推一体化的资源调度与高效协同,为钢铁行业的数智化转型构建了坚实的算力底座。层面,方案构建覆盖“工业数采→边缘IT/OT融合→统一数据湖→数据治理平台→数据应用”全链路的一站式数据治理与流通平台,打通生产现场与管理系统间的数据壁垒,让数据“采得到、流得动、用得好”,加速数据价值从生产现场向经营决策层流动释放。湘潭钢铁集团的钢铁数智云,是钢铁工业智能云建设的标杆案例。

华为云官方博客 526

LakeWatch——MRS 智能运维Agent

从资源池、队列、作业等多个维度,对集群CPU与内存资源进行精细化分析与对比,直观呈现不同时间段的空闲、满载等使用状态,识别资源浪费,指导治理优化,为扩缩容决策提供数据支撑。对HDFS存储进行多维度深度分析(目录、用户、用户组等),涵盖使用量、增量、文件大小分布及数据热度等指标,帮助快速识别增长较快的目录、长期未访问的文件,统计目录文件数量与小文件占比,评估HDFS总存储量与扩缩容需求,为存储治理与资源规划提供全面数据支撑。Agent主动巡检,识别异常趋势并提前预警,让运维从"事后处理"转向"事前预防"。

华为云官方博客 515

华为云专题文档发布:丰富的AI案例、选型指导和概念解读

发布 “云服务选型”、“云计算概念”专题,提供云服务选型指导,助您选择匹配业务的云服务,解读云计算相关概念,开启云上学习之路。开发者工具和文档专区上线,提供从学习、实践到反馈的全链路支持。帮助中心新增100余篇AI案例。

华为云官方博客 286

一个人,也能用AI做点“星东西”

华为云星耀创想者大赛-2026华为云OPC创意大赛等你来~

华为云官方博客 290

从需求到可执行工作项:MCP+Skill 让智能体规划真正落地

回顾整个体验,以前让智能体帮我拆需求,它是洋洋洒洒给我列了一大篇 Markdown,看着挺像那么回事,但最后还是得我一条条往 CodeArts Req 里搬,搬完再手动挂父子关系、排日期,拆需求五分钟,搬运两小时。现在好了,MCP 给智能体接上了"手",Skill 给它装上了"项目经理的脑子",一句话下去,34 个工作项连带排期、层级关系全给我建好了,甘特图一拉,齐刷刷都在两周内,节省了多少工作量啊,美滋滋。本次实操在码道代码智能体基础上,构建了一套"需求→可执行工作项"的自动化规划方案。

华为云官方博客 576

华为云码道「码力续航计划」更新!

✅上新GLM‑5.3‑Flash,高速响应,代码生成、工程解析、Agent调试高效输出。新增GLM‑5.3‑Flash福利模型,每日解锁1000万免费Tokens。● 本次活动共发放总量价值100万元Tokens,发完即止!把耗算力的编码重活,交给华为云码道代码智能体🚀🚀。● 每日额度准时刷新,当日清零、次日满血重置。✅复杂算法、大项目解析、批量代码生成随便跑。✅不用抠额度、不用算消耗,放开调试大胆迭代。✅无需额外操作,登录即送,直接切换模型使用。● 把算力交给码道,让撸码不再内耗👏🏻。

华为云官方博客 686

【公共云三十问 之二十四】国计民生之交通:交通云如何铺就数智通衢新坦途?

交通行业作为支撑实体经济的关键基础设施,涵盖公路、铁路、机场、港口、地铁等众多子领域,其中,公路网络作为综合交通运输体系的基础骨架,承担着全国超过70%的客货运量,其数字化、智能化转型的需求尤为迫切。方面,提供Agent开发框架、知识库管理、RAG工程、意图识别、静态应用编排及模型评测等能力,支持客户将行业知识、业务流程与AI能力深度融合,快速构建面向收费稽核、路网调度、应急处置等场景的智能应用。开发并实现落地应用,全面覆盖建设、管理、养护、运营、服务、安全、办公七大业务领域。

华为云官方博客 461

【公共云三十问 之二十五】国计民生之电力:电力云如何点亮数智电力新引擎?

方案构建了覆盖数据获取、质量评估到标准化处理的全链路能力。基于公共云服务商智算底座及气象大模型,通过时空图神经网络重新建模产流机制,中国华电建成超50TB多源融合数据集,突破时空建模与机理融合等五大关键技术,短期径流预测精度较传统机理模型提升5个百分点以上,实现15天中期径流预测精度超85%,推理效率达秒级。基于气象大模型的基础架构与预训练能力,客户可直接在大模型之上开展增量训练与微调,充分利用场站所在区域的高精度历史数据(如3公里、1公里分辨率),针对不同场站和区域的地形地貌与气候特征进行模型调优。

华为云官方博客 381
上一篇: 基于开发者空间GaussDB云数据库的PLpgSQL实践二
下一篇: 开发者空间仓颉初体验:开启仓颉语言的神秘大门
华为云开发者联盟
华为云开发者联盟 企业官方账号 企业官方账号
博客等级 码龄10年 72万+粉丝 5985原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值