【Postgres】11、PROCEDURE 存储过程、FUNCTION 函数、使用方式和区别

文章目录

  • 一、PROCEDURE
    • 1.1 语法
    • 1.2 描述
    • 1.3 参数
    • 1.4 示例
  • 二、FUNCTION
    • 2.1 语法
    • 2.2 重载
    • 2.3 示例
    • 2.4 兼容性
    • 2.5 示例
      • 2.5.1 declare variable 定义变量
      • 2.5.2 declare、ARRAY、ANY
        • 2.5.2.1 ARRAY 和 ANY
  • 三、其他
    • 3.1 PL/pgSQL

在PostgreSQL中,存储过程(Procedure)和函数(Function)是两种可执行的数据库对象,它们之间有一些区别。以下是它们的主要区别:

  1. 返回值:函数具有返回值,而存储过程可以没有返回值或返回多个结果集。
  2. 调用方式:函数可以像普通的SQL表达式一样调用,可以在查询中直接使用函数的返回值。而存储过程需要使用CALL语句来调用,并且无法将其嵌入到查询中。
  3. 事务控制:函数在调用时会自动启动一个事务,并且可以使用COMMIT或ROLLBACK语句来控制事务的提交或回滚。存储过程可以在其中包含多个SQL语句,但不会自动启动事务,需要手动控制事务的开始和结束。
  4. 参数传递:函数和存储过程都可以接收参数,但在函数中,参数可以通过IN、OUT和INOUT模式来指定,而存储过程中的参数只能通过IN模式传递。
  5. 使用场景:函数通常用于执行一系列计算或操作,并返回结果。存储过程通常用于执行一系列的数据库操作,例如数据加载、数据清理、数据迁移等。存储过程通常用于封装复杂的业务逻辑,并且可以被其他应用程序或过程调用。

虽然存储过程和函数在某些方面有区别,但它们也有一些共同点,例如都可以使用PL/pgSQL等编程语言编写,都可以访问数据库对象和执行SQL语句。选择使用存储过程还是函数取决于具体的需求和使用场景。

一、PROCEDURE

https://www.postgresql.org/docs/current/sql-createprocedure.html

1.1 语法

CREATE [ OR REPLACE ] PROCEDURE
    name ( [ [ argmode ] [ argname ] argtype [ { DEFAULT | = } default_expr ] [, ...] ] )
  { LANGUAGE lang_name
    | TRANSFORM { FOR TYPE type_name } [, ... ]
    | [ EXTERNAL ] SECURITY INVOKER | [ EXTERNAL ] SECURITY DEFINER
    | SET configuration_parameter { TO value | = value | FROM CURRENT }
    | AS 'definition'
    | AS 'obj_file', 'link_symbol'
    | sql_body
  } ...

1.2 描述

可以指定在 某 schema 下,创建 procedure,否则在当前 schema 下创建。

procedure 和 function,如果有不同的参数,是可以重名的(即 overloading)。

CREATE OR REPLACE PROCEDURE 可以更改 body。但正因为 overloading,所以不能通过 CREATE OR REPLACE PROCEDURE 来更改 name 或 arguments。(如果尝试的话,会 create 一个新的,不同的 procedure)。

必须有 USAGE 权限的用户才能创建 PROCEDURE。

使用 CREATE OR REPLACE PROCEDURE 时,ownership 和 permission 不会变化。

1.3 参数

name:名称

argmode:IN、OUT、INOUT、VARIADIC,默认是 IN
argname:参数名称
argtype:是存储过程参数的数据类型。可以是基本类型、复合类型、域类型,或者引用表列的类型。参数类型可以选择模式限定,如果需要的话。根据实现的编程语言,也可以指定“伪类型”,例如cstring。伪类型表示实际参数类型不完全指定,或者不属于普通SQL数据类型集合之内。
通过写入table_name.column_name%TYPE,可以引用列的类型。使用这个特性有时可以帮助使存储过程独立于对表定义的更改。

default_expr: 如果未指定参数,则用作默认值的表达式。该表达式必须对参数的实参类型是强制的。带有缺省值的参数后面的所有输入参数也必须具有缺省值。

lang_name: 实现过程所使用的语言的名称。它可以是SQL、C、INTERNAL或用户定义的过程语言的名称,例如plpgsql。如果指定了SQL_BODY,则默认为SQL。不建议使用单引号将名称括起来,并且需要大小写匹配。

TRANSFORM { FOR TYPE type_name } [, … ] }
列出应应用哪些转换对过程的调用。转换在SQL类型和语言特定的数据类型之间进行转换;请参阅创建转换。过程语言实现通常具有内置类型的硬编码知识,因此不需要在这里列出这些知识。如果过程语言实现不知道如何处理类型,并且没有提供转换,则它将退回到转换数据类型的默认行为,但这取决于实现。

1.4 示例

CREATE PROCEDURE insert_data(a integer, b integer)
LANGUAGE SQL
AS $$
INSERT INTO tbl VALUES (a);
INSERT INTO tbl VALUES (b);
$$;
CREATE PROCEDURE insert_data(a integer, b integer)
LANGUAGE SQL
BEGIN ATOMIC
  INSERT INTO tbl VALUES (a);
  INSERT INTO tbl VALUES (b);
END;

调用方式为

CALL insert_data(1, 2);

二、FUNCTION

http://postgres.cn/docs/14/sql-createfunction.html

2.1 语法

CREATE [ OR REPLACE ] FUNCTION
    name ( [ [ argmode ] [ argname ] argtype [ { DEFAULT | = } default_expr ] [, ...] ] )
    [ RETURNS rettype
      | RETURNS TABLE ( column_name column_type [, ...] ) ]
  { LANGUAGE lang_name
    | TRANSFORM { FOR TYPE type_name } [, ... ]
    | WINDOW
    | { IMMUTABLE | STABLE | VOLATILE }
    | [ NOT ] LEAKPROOF
    | { CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT }
    | { [ EXTERNAL ] SECURITY INVOKER | [ EXTERNAL ] SECURITY DEFINER }
    | PARALLEL { UNSAFE | RESTRICTED | SAFE }
    | COST execution_cost
    | ROWS result_rows
    | SUPPORT support_function
    | SET configuration_parameter { TO value | = value | FROM CURRENT }
    | AS 'definition'
    | AS 'obj_file', 'link_symbol'
    | sql_body
  } ...

CREATE FUNCTION定义一个新函数。CREATE OR REPLACE FUNCTION将创建一个新函数或者替换一个现有的函数。要定义一个函数,用户必须具有该语言上的USAGE特权。

如果包括了一个模式名,那么该函数会被创建在指定的模式中。否则,它会被创建在当前模式中。新函数的名称不能匹配同一个模式中具有相同输入参数类型的任何现有函数或过程。不过,不同参数类型的函数和过程能够共享一个名字(这被称作重载)。

要替换一个现有函数的当前定义,可以使用CREATE OR REPLACE FUNCTION。但不能用这种方式更改函数的名称或者参数类型(如果尝试这样做,实际上就会创建一个新的不同的函数)。还有,CREATE OR REPLACE FUNCTION将不会让你更改一个现有函数的返回类型。要这样做,你必须先删除再重建该函数(在使用OUT参数时,这意味着除了删除函数之外无法更改任何OUT参数的类型)。

当CREATE OR REPLACE FUNCTION被用来替换一个现有的函数,该函数的拥有权和权限不会改变。所有其他的函数属性会按照该命令中所指定的或者隐含的来赋值。必须拥有(包括成为拥有角色的成员)该函数才能替换它。

如果你删除并且重建一个函数,新函数将和旧的不一样,你将必须删掉引用旧函数的现有规则、视图、触发器等。使用CREATE OR REPLACE FUNCTION更改一个函数定义不会破坏引用该函数的对象。还有,ALTER FUNCTION可以被用来更改一个现有函数的大部分辅助属性。

创建该函数的用户将成为该函数的拥有者。

要创建一个函数,你必须拥有参数类型和返回类型上的USAGE特权。

2.2 重载

PostgreSQL允许函数重载,也就是说同一个名称可以被用于多个不同的函数,只要它们具有可区分的输入参数类型。不管是否使用它,在有些用户不信任另一些用户的数据库中调用函数时,这种兼容性需要安全性的预防措施,请参考第 10.3 节。

如果两个函数具有相同的名称和***输入***参数类型,它们被认为相同(不考虑任何OUT参数)。因此这些声明会冲突:

CREATE FUNCTION foo(int) ...
CREATE FUNCTION foo(int, out text) ...

具有不同参数类型列表的函数在创建时将不会被认为是冲突的,但是如果默认值被提供,在使用时它们有可能会冲突。例如,考虑

CREATE FUNCTION foo(int) ...
CREATE FUNCTION foo(int, int default 42) ...

调用foo(10)将会失败,因为在要决定应该调用哪个函数时会有歧义。

2.3 示例

使用SQL函数对两个整数相加:

CREATE FUNCTION add(integer, integer) RETURNS integer
    AS 'select $1 + $2;'
    LANGUAGE SQL
    IMMUTABLE
    RETURNS NULL ON NULL INPUT;

同一个函数以更符合SQL习惯的样式编写,使用参数名称和未加引号的函数体,如下:

CREATE FUNCTION add(a integer, b integer) RETURNS integer
    LANGUAGE SQL
    IMMUTABLE
    RETURNS NULL ON NULL INPUT
    RETURN a + b;

在PL/pgSQL中,使用一个参数名称增加一个整数:

CREATE OR REPLACE FUNCTION increment(i integer) RETURNS integer AS $$
	BEGIN
	    RETURN i + 1;
	END;
$$ LANGUAGE plpgsql;

返回一个包含多个输出参数的记录:

CREATE FUNCTION dup(in int, out f1 int, out f2 text)
    AS $$ SELECT $1, CAST($1 AS text) || ' is text' $$
    LANGUAGE SQL;

SELECT * FROM dup(42);

-- code result:
postgres=# SELECT * FROM dup(42);
(42,"42 is text")

你可以用更复杂的方式(用一个显式命名的组合类型)来做同样的事情:

CREATE TYPE dup_result AS (f1 int, f2 text);

CREATE FUNCTION dup(int) RETURNS dup_result
    AS $$ SELECT $1, CAST($1 AS text) || ' is text' $$
    LANGUAGE SQL;

SELECT * FROM dup(42);

-- code result:
postgres=# SELECT * FROM dup(42);
 f1 |     f2
----+------------
 42 | 42 is text

另一种返回多列的方法是使用一个TABLE函数:

CREATE FUNCTION dup(int) RETURNS TABLE(f1 int, f2 text)
    AS $$ SELECT $1, CAST($1 AS text) || ' is text' $$
    LANGUAGE SQL;

SELECT * FROM dup(42);

-- code result:
postgres=# SELECT * FROM dup(42);
 f1 |     f2
----+------------
 42 | 42 is text

不过,TABLE 函数与之前的例子不同,因为它实际返回了一个记录集合而不只是一个记录。

2.4 兼容性

SQL标准中定义了CREATE FUNCTION命令。 PostgreSQL实现可以以兼容的方式使用,但有许多扩展。 相反,SQL标准指定了许多未在PostgreSQL中实现的可选功能。

以下是重要的兼容性问题:

  • OR REPLACE是PostgreSQL的扩展。
  • 为了与其他一些数据库系统兼容,argmode 可以在*argname*之前或之后写入。 但只有第一种方式符合标准。
  • 对于参数默认值,SQL标准仅指定带有DEFAULT关键字的语法。 =的语法是在T-SQL和Firebird中被使用的。
  • SETOF修饰符是PostgreSQL的扩展。
  • 只有SQL是被标准化的一个语言。
  • 除了 CALLED ON NULL INPUTRETURNS NULL ON NULL INPUT以外的所有其他属性都没有标准化。
  • 对于LANGUAGE SQL函数的主体,SQL标准只指定了 *SQL_body*形式。

简单的LANGUAGE SQL函数可以以既符合标准又可移植到其他实现的方式编写。 使用高级特性、优化属性或其他语言的更复杂的函数必然在很大程度上特定于PostgreSQL。

2.5 示例

2.5.1 declare variable 定义变量

DECLARE variable_name [ CONSTANT ] data_type [ { DEFAULT | := } initial_value ];

其中:
DECLARE:用于声明一个变量。
variable_name:变量的名称。
[ CONSTANT ]:可选项,用于指定变量是否为常量。
data_type:变量的数据类型,可以是基本数据类型、复合类型或自定义类型。
[ DEFAULT | := ]:可选项,用于指定变量的初始值。DEFAULT关键字和:=赋值符号都可以用于指定初始值。
initial_value:变量的初始值。

以下是一个示例,演示在PostgreSQL函数中声明和使用变量的过程:

CREATE OR REPLACE FUNCTION calculate_sum(a INT, b INT)
RETURNS INT AS $$

DECLARE
	result INT;
BEGIN
	result := a + b;
	RETURN result;
END;

$$ LANGUAGE plpgsql;

在上述示例中,函数calculate_sum声明了一个名为result的整数变量,并将ab的和赋值给该变量。最后,函数返回了变量result的值。

2.5.2 declare、ARRAY、ANY

-- 建表
CREATE TABLE a(id TEXT, ts BIGINT);
INSERT INTO a VALUES ('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5);
postgres=# SELECT * FROM a;
 id | ts
----+----
 a  |  1
 b  |  2
 c  |  3
 d  |  4
 e  |  5
(5 rows)

-- 建FUNCTION
CREATE OR REPLACE FUNCTION f(id_arr TEXT[], src_start_ts BIGINT, src_end_ts BIGINT, tgt_start_ts BIGINT)
RETURNS VOID AS $$
DECLARE
    offset_ms BIGINT;
BEGIN
    offset_ms := tgt_start_ts - src_start_ts; -- 偏移多少毫秒
    DROP TABLE IF EXISTS t; -- 临时表
    CREATE TABLE t AS SELECT * FROM a WHERE id = ANY(id_arr) AND ts >= src_start_ts AND ts <= src_end_ts; -- 查原始表a的数据
    UPDATE t SET ts = ts + offset_ms; -- 执行偏移(在临时表)
    INSERT INTO a SELECT * FROM t; -- 将偏移写入原始表
END;
$$ LANGUAGE plpgsql;

-- 执行
SELECT f(ARRAY['a', 'b', 'c', 'd', 'e'], 2, 4, 10); -- 操作从ts=2到ts=4的三行数据,使它们的ts向后偏移10-2=8个单位,从而得到ts=10到ts=12的三行数据并写入原始表
postgres=# SELECT * FROM a;
 id | ts
----+----
 a  |  1
 b  |  2
 c  |  3
 d  |  4
 e  |  5
 b  | 10
 c  | 11
 d  | 12
(8 rows)
2.5.2.1 ARRAY 和 ANY

在PostgreSQL中,可以使用关键字IN来判断一个值是否存在于一个数组中。以下是使用IN操作符来检查一个值是否存在于数组中的示例:

SELECT * FROM my_table WHERE my_column IN ('value1', 'value2', 'value3');

在上述示例中,my_table是表名,my_column是包含数组的列名。'value1', 'value2', 'value3'是要检查的值的列表。如果my_column列中的值与列表中的任何一个值匹配,那么该行将被返回。

如果你想要检查一个值是否存在于一个数组类型的参数中,可以使用ANY关键字。以下是检查一个值是否存在于数组参数中的示例:

CREATE OR REPLACE FUNCTION my_function (my_array text[], value text)
RETURNS boolean AS $$
BEGIN
	RETURN value = ANY(my_array);
END;
$$ LANGUAGE plpgsql;

在上述示例中,my_array是一个文本数组类型的参数,value是要检查的值。函数使用ANY关键字来判断value是否存在于my_array中,并返回布尔值。

这是使用IN操作符和ANY关键字在PostgreSQL中检查一个值是否存在于一个数组中的常见方法。根据实际需求,你可以根据这些示例进行调整和修改。

三、其他

3.1 PL/pgSQL

PL/pgSQL是PostgreSQL数据库中的一种过程化语言(Procedural Language),用于编写存储过程、触发器、函数和其他数据库相关的程序。PL/pgSQL是PostgreSQL的默认过程化语言,提供了丰富的功能和语法,可以用于编写复杂的业务逻辑和数据处理逻辑。

PL/pgSQL基于SQL语言,结合了流程控制结构(如条件语句、循环语句)和SQL语句,使开发人员能够在数据库中编写更灵活和强大的程序。它支持变量声明、条件判断、循环、异常处理等常见的编程特性,并且可以直接访问数据库对象和执行SQL查询。

使用PL/pgSQL,开发人员可以在数据库中创建存储过程,以便执行一系列的数据库操作,如数据加载、数据清理、数据转换等。它还可以用于编写触发器,以在数据库表上定义特定的触发行为。此外,PL/pgSQL还可以编写函数,用于执行计算、数据处理和数据转换等任务。

总之,PL/pgSQL是PostgreSQL数据库中的一种过程化语言,用于编写复杂的数据库程序和逻辑。它是PostgreSQL强大而灵活的编程工具之一。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/395596.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

家中R4S软路由iStoreOS配置内网穿透服务实现远程访问公司电脑桌面

文章目录 简介一、配置远程桌面公网地址二、家中使用永久固定地址 访问公司电脑**具体操作方法是&#xff1a;** 简介 软路由是PC的硬件加上路由系统来实现路由器的功能&#xff0c;也可以说是使用软件达成路由功能的路由器。 使用软路由控制局域网内计算机的好处&#xff1a…

【Jvm】性能调优(上)线上问题排查工具汇总

文章目录 一.互联网概念1.产品闭环和业务闭环2.软件设计中的上游和下游3.JDK运行时常量池 二.CPU相关概念1.查询CPU信息2.CPU利用率&#xff08;CPU utilization&#xff09;和 CPU负载&#xff08;CPU load&#xff09;2.1.如何理解CPU负载2.2.top命令查看CPU负载均值2.3.CPU负…

更改WordPress作者存档链接author和Slug插件Edit Author Slug

WordPress默认所有用户的存档永久链接都是/author/username/&#xff0c;不管是管理员还是订阅者或贡献者或作者或编辑。如果你想要自定义用户存档链接&#xff0c;比如根据角色不同使用不一样的author&#xff0c;或者自定义作者链接中的用户名Slug&#xff0c;那么建议考虑使…

如何使用Docker部署Drupal并结合cpolar实现固定公网地址访问

文章目录 前言1. Docker安装Drupal2. 本地局域网访问3 . Linux 安装cpolar4. 配置Drupal公网访问地址5. 公网远程访问Drupal6. 固定Drupal 公网地址 前言 Dupal是一个强大的CMS&#xff0c;适用于各种不同的网站项目&#xff0c;从小型个人博客到大型企业级门户网站。它的学习…

选择结构switch

一、执行流程 所有case都和表达式的值不匹配&#xff0c;就会执行default语句体部分 从被匹配的位置开始执行&#xff0c;如果遇到break&#xff0c;那么退出选择结构 二、注意事项 1、case后面的【常量值】不能重复&#xff0c;不然编译器会报错 2、switch后面的小括号只…

MoonBit新增functional for loop控制流支持

1. 增加functional for loop控制流支持 与传统的命令式for loop 不同&#xff0c;循环变量是不可变的。这样的设计将来也容易抽取出来做形式化验证&#xff1a; fn init {for i 0; i < 5; i i 1 {debug(i)// i i 4 error: The variable i is not mutable.} }输出&am…

一文概括|CSC访问学者/博士后/联培申请及派出流程详解

为帮助申请者了解国家留学基金委&#xff08;CSC&#xff09;的政策&#xff0c;以及申报及派出的全过程&#xff0c;知识人网小编利用本文简略介绍并提出规划建议。 公派留学包括国家、地方&#xff08;含省市、行业、学校医院等单位&#xff09;资助派出。而国家公派则由留学…

十字星K线(Doji)含义,fpmarkets澳福一分钟讲解

许多新手交易者遇到过这种奇怪的烛台&#xff0c;看起来就像一个十字架&#xff0c;没有主体上下有长长的影子&#xff0c;fpmarkets澳福肯定的告诉各位投资者&#xff0c;这种就是十字星K线(用Doji表示)&#xff0c;开盘价与收盘价一致&#xff0c;价格运动已经停止时出现在烛…

洛谷C++简单题小练习day15—计算阶乘小程序(不用循环)

day15--计算阶乘小程序--2.19 习题概述 题目描述 求 n!&#xff0c;也就是 123⋯n。 挑战&#xff1a;尝试不使用循环语句&#xff08;for、while&#xff09;完成这个任务。 输入格式 第一行输入一个正整数 n。 输出格式 输出一个正整数&#xff0c;表示 n! 代码部分 …

从零开始的 dbt 入门教程 (dbt core 开发进阶篇)

引 在上一篇文章中&#xff0c;我们花了专门的篇幅介绍了 dbt 更多实用的命令&#xff0c;那么我们继续按照之前的约定来聊 dbt 中你可能会遇到的疑惑以及有用的概念&#xff0c;如果你是 dbt 初学者&#xff0c;我相信如下知识点一定会对你有极大的帮助&#xff1a; 了解 db…

简单贪吃蛇模拟(C语言版本·)

简单贪吃蛇模拟&#xff08;C语言版本&#xff09; 一、所需win32 API知识二、游戏逻辑实现 一、所需win32 API知识 1.在这儿&#xff0c;直接弱化概念&#xff0c;把在贪吃蛇中用到的API知识说一下&#xff01;  1.1用cmd命令来设置控制台窗口的长宽   1.2.用title 指令…

python入门----基础

这里写目录标题 重点虚拟环境/与//的区别/// 关于print字符串可以用号拼接单双引号转义符换行三引号 变量变量的定义变量名的命名 API库导库以及使用 注释单行注释多行注释 数据类型strboolNoneTypetype函数 交互模式介绍开启 input作用延伸 if-else条件嵌套语句逻辑运算符内容…

世界顶级名校计算机专业,都在用哪些书当教材?

前言 在当今信息化、数字化时代&#xff0c;计算机科学已成为全球最为热门和重要的学科之一。世界顶级名校的计算机专业&#xff0c;更是培养未来行业领袖和创新人才的重要基地。那么&#xff0c;这些名校的计算机专业究竟使用哪些教材呢&#xff1f;这些教材又具有哪些特色和…

11. Springboot集成Dubbo3(二)示例demo

目录 1、前言 2、注册中心 3、快速开始 3.1、添加dubbo3依赖 3.2、dubbo3-api ​编辑 3.3、dubbo3-server 3.3.1、添加依赖 3.3.2、实现IUserService 3.3.3、添加配置文件application.properties 3.3.4、修改Application启动类 3.3.5、出错解决 3.4、dubbo3-porta…

Golang 更严格的代码格式化工具 gofumpt

一、前言 gofmt 是 golang 自带的代码自动格式化工具&#xff0c;是保证 Go 代码风格一致的大杀器。我们这次要推荐的 gofumpt 在 gofmt 的基础上添加了一系列更加严格的格式化规则&#xff0c;并保证了对 gofmt 的兼容。 二、gofumpt 简介 gofumpt(https://github.com/mvda…

职业性格在求职应聘和跳槽中的作用

性格测试对跳槽者的影响大不大&#xff1f;首先我们要弄清楚两个问题&#xff0c;性格对我们的职业生涯又没有影响&#xff0c;性格测试是什么&#xff0c;职场中有哪些应用&#xff1f;性格可以说从生下来就有了&#xff0c;随着我们的成长&#xff0c;我们的性格也越来越根深…

2024开工大吉,便宜寄快递该怎么选呢?

随着春节的结束&#xff0c;大部分人回到了工作的岗位&#xff0c;相信许多人还沉浸在过年的喜悦的氛围中呢&#xff0c;但是我们可以期盼下一个春节的到来了&#xff0c;言归正传&#xff0c;工作中总会收发快递了&#xff0c;尤其是最近&#xff0c;需要联络客户的感情了&…

串口通信功能介绍和配置

用户GPIO中其实很多IO口可以复用成串口功能&#xff08;可查看复用定义表&#xff09;&#xff0c;但是我们这里按照默认定义所以只对8脚、9脚进行复用测试&#xff0c;引脚定义入下图&#xff1a; 硬件连接 测试串口我们需要一个串口调试工具&#xff0c;可以使用串口烧录工具…

练习题解(关于最短路径)

目录 1.租用游艇 2.邮递员送信 3.【模板】单源最短路径&#xff08;标准版&#xff09; 1.租用游艇 P1359 租用游艇 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 输入数据&#xff1a; 3 5 15 7 因为这道题数据不大&#xff0c;所有我们直接使用Floyd 算法。 这道题大…

解决传统单一模态难题!多模态图学习新SOTA来了!

多模态图学习是一种结合了图神经网络和多模态数据集成的学习方法&#xff0c;它涉及了数据科学、机器学习、图神经网络、多模态分析等多个前沿领域。这种跨学科特性为我们提供了丰富的创新点和探索空间。因此&#xff0c;多模态图学习也是发表高质量论文的好方向。 通过整合和…
最新文章