postgresql-存储过程
postgresql-存储过程
- 简述
- PL/pgSQL 代码块结构
- 示例
- 嵌套子块
- 声明与赋值
- 控制结构
- IF 语句
- CASE 语句
- 简单case语句
- 搜索 CASE 语句
- 循环语句
- continue
- while
- for语句
- 遍历查询结果
- foreach
- 游标
- 游标传参
- 错误处理
- 报告错误和信息
- 检查断言
- 捕获异常
- 自定义函数
- 重载
- VARIADIC
- 存储过程
- 示例
- 事务管理
简述
除了标准 SQL 语句之外,PostgreSQL 还支持使用各种过程语言(例如 PL/pgSQL、C、PL/Tcl、
PL/Python、PL/Perl、PL/Java 等 )创建复杂的过程和函数,称为存储过程(Stored Procedure)
和自定义函数(User-Defined Function)。存储过程支持许多过程元素,例如控制结构、循环和
复杂的计算。
使用存储过程带来的好处包括:
- 减少应用和数据库之间的网络传输。所有的 SQL 语句都存储在数据库服务器中,应用程
序只需要发送函数调用并获取除了结果,避免了发送多个 SQL 语句并等待结果 - 提高应用的性能。因为自定义函数和存储过程进行了预编译并存储在数据库服务器中。
- 可重用性。存储过程和函数的功能可以被多个应用同时使用。
当然,使用存储过程也可能带来一些问题: - 导致软件开发缓慢。因为存储过程需要单独学习,而且很多开发人员并不具备这种技能。
- 不易进行版本管理和代码调试。
- 不同数据库管理系统之间无法移植,语法存在较大的差异。
本文主要介绍 PL/pgSQL 存储过程,它和 Oracle PL/SQL 非常类似,是 PostgreSQL 默认支
持的存储过程。使用 PL/pgSQL 的原因包括: - PL/pgSQL 简单易学,无论是否具有编程基础都能够很快学会。
- PL/pgSQL 是 PostgreSQL 默认支持的过程语言,PL/pgSQL 开发的自定义函数可以和内置
函数一样使用。 - PL/pgSQL 提高了许多强大的功能,例如游标,可以实现复杂的函数。
PL/pgSQL 代码块结构
/** label 是一个可选的代码块标签,可以用于 EXIT 语句退出指定的代码块,或者限定变量的名称* DECLARE 是一个可选的声明部分,用于定义变量* BEGIN 和 END 之间是代码主体,也就是主要的功能代码;所有的语句都使用分号(;)结束* END 之后的分号表示代码块结束。* */
[ <<label>> ]
[ DECLAREdeclarations ]
BEGINstatements;...
END [ label ];
示例
/** 个匿名块,与此相对的是命名块(也就是存储过程和函数)。其中,DO 语句用于* 执行匿名块;我们定义了一个字符串变量 name,然后给它赋值并输出一个信息;RAISE NOTICE用于输出通知消息。* $$用于替换单引号(')* */
do $$
declare name text;
beginname :='PL/pgSQL';raise notice 'Hello %!',name; end $$;
/** $$用于替换单引号('),因为 PL/pgSQL 代码主体必须是字符串文本,* 意味着代码中所有的单引号都必须转义(重复写两次)
*/
DO
'DECLAREname text;
BEGINname := ''PL/pgSQL'';RAISE NOTICE ''Hello %!'', name;
END ';
嵌套子块
PL/pgSQL 支持代码块的嵌套,也就是将一个代码块嵌入其他代码块的主体中。被嵌套的代
码块被称为子块(subblock
),包含子块的代码块被称为外部块(subblock)
。子块可以将代码
进行逻辑上的拆分,子块中可以定义与外部块重名的变量,而且在子块内拥有更高的优先级
DO $$
<<outer_block>>
declarename text;
BEGINname := 'outer_block';RAISE NOTICE 'This is %', name;DECLAREname text := 'sub_block';BEGINRAISE NOTICE 'This is %', name;RAISE NOTICE 'The name FROM the outer block is %', outer_block.name;END;RAISE NOTICE 'This is %', name;END outer_block $$;
声明与赋值
/*variable_name 是变量的名称,通常需要指定一个有意义的名称;data_type 是变量的
类型,可以是任何 SQL 数据类型;如果指定了 NOT NULL,必须使用后面的表达式为变量指定
初始值。赋值使用:=*/
variable_name data_type [ NOT NULL ] [ { DEFAULT | := | = } expression ];
DO $$
declare
id integer;
-- price默认值是0
price numeric(5,2) default 0.0;
name text;
url varchar :='http://mysite.com';
--行类型的变量,可以存储查询语句返回的数据行(数据行的结构要和 employees相同)
myrow employees%rowtype;
-- myfield 的数据类型取决于 empoyees.first_name 字段的定义
myfield employees.first_name%type;
-- myprice 和 price 的类型一致。
myprice price%type;
-- 记录类型变量
-- 记录类型的变量没有预定义的结构,只有当变量被赋值时才确定,而且可以在运行时被改变。
-- 记录类型的变量可以用于任意查询语句或者 FOR 循环变量
arow RECORD;
-- 使用 ALIAS 定义一个变量别名
myprice1 ALIAS FOR myprice;
-- 在定义变量时指定了 CONSTANT 关键字,意味着定义的是常量。常量的值需要在声明时初始化,并且不能修改
PI CONSTANT NUMERIC := 3.14159265;
beginid := 1;name :='tony';raise notice 'id = %',id;raise notice 'price = %',price;raise notice 'name = %',name;raise notice 'url =%',url;raise notice '常量PI=%',PI;
end $$;
控制结构
IF 语句
- IF … THEN … END IF
- IF … THEN … ELSE … END IF
- IF … THEN … ELSIF … THEN … ELSE … END IF
-- 简单的if语句
DO $$
beginif 2>1 thenraise notice '2大于1';end if;
end $$;
-- if ... else
DO $$
beginif 2>3 thenraise notice '2大于3';elseraise notice '2不大于3';end if;
end $$;
-- if ... else 多个条件分支
DO $$
beginif 2>3 thenraise notice '2大于3';elseif 2=3 thenraise notice '2等于3';elseraise notice '2不大于3';end if;
end $$;
CASE 语句
CASE 语句,同样可以根据不同的条件执行不同的分支语句。CASE 语句分为两种:简单 CASE 语句和搜索 CASE 语句。
简单case语句
-- 语法
CASE search-expressionWHEN expression [, expression [ ... ]] THENstatements[ WHEN expression [, expression [ ... ]] THENstatements... ][ ELSEstatements ]
END CASE;
-- case 简单语句
DO $$
declare i integer := 1;
begincase iwhen 1,2 thenraise notice '1或者2';when 3 thenraise notice '3';elseraise notice '其他值';end case;
end $$;
搜索 CASE 语句
-- 语法
CASEWHEN boolean-expression THENstatements[ WHEN boolean-expression THENstatements... ][ ELSEstatements ]
END CASE;
-- 搜索case 简单语句
DO $$
declare i integer := 25;
begincase when i between 1 and 10 thenraise notice '[1-10]';when i between 11 and 20 thenraise notice '[11-20]';elseraise notice '其他值';end case;
end $$;
循环语句
PostgreSQL 提供 4 种循环执行命令的语句:LOOP、WHILE、FOR 和 FOREACH 循环,以
及循环控制的 EXIT 和 CONTINUE 语句。
-- LOOP 用于定义一个无限循环语句:
-- 一般需要使用 EXIT 或者 RETURN 语句退出循环,label 可以用于 EXIT 或者 CONTINUE 语
-- 句退出或者跳到执行的嵌套循环中
[ <<label>> ]
LOOPstatements
END LOOP [ label ];
-- loop循环
DO $$
declare i integer := 1;
beginloop-- exit退出循环exit when i = 5;raise notice '第%次执行!',i;i :=i+1;end loop;
end $$;
continue
-- loop循环
DO $$
declare i integer := 0;
beginloop-- exit退出循环exit when i = 10;i := i+1;-- continue 忽略后面的语句,直接进入下一次循环-- mod(i,2) =0;偶数跳过执行continue when mod(i,2) =0;raise notice '第%次执行!',i;end loop;
end $$;
while
-- 语法
-- 当表达式 boolean-expression 的值为真时,循环执行其中的语句;然后重新计算表达式的值,
-- 当表达式的值假时退出循环
[ <<label>> ]
WHILE boolean-expression LOOPstatements
END LOOP [ label ];
-- while语句
DO $$
declare i integer := 0;
beginwhile i <10 loopi := i+1;raise notice '第%次执行',i;end loop;
end $$;
for语句
-- 语法
-- FOR 循环默认从小到大进行遍历,REVERSE 表示从大到小遍历;BY 用于指定每次的增量,
-- 默认为 1
[ <<label>> ]
FOR name IN [ REVERSE ] expression .. expression [ BY expression ] LOOPstatements
END LOOP [ label ];
-- for语句
DO $$
begin-- 变量 i 不需要提前定义,可以在 FOR 循环内部使用。-- by 2每次增量为2for i in reverse 20..10 by 2 loopraise notice '第%次循环!',i;end loop;
end $$;
-- for语句
DO $$
begin-- 变量 i 不需要提前定义,可以在 FOR 循环内部使用。-- by 2每次增量为2for i in 1..10 by 2 loopraise notice '第%次循环!',i;end loop;
end $$;
遍历查询结果
-- 语法
-- target 可以是一个 RECORD 变量、行变量或者逗号分隔的标量列表。在循环中,target
-- 代表了每次遍历的行数据。
[ <<label>> ]
FOR target IN query LOOPstatements
END LOOP [ label ];
-- for语句遍历查询结果
DO $$
declare
emp record;
beginfor emp in (select * from employees limit 5) loopraise notice '员工信息: %, %, %',emp.first_name,emp.last_name,emp.salary;end loop;
end $$;
foreach
-- 语法
[ <<label>> ]
FOREACH target [ SLICE number ] IN ARRAY expression LOOPstatements
END LOOP [ label ];
如果没有指定 SLICE
或者指定 SLICE 0
,FOREACH
将会变量数组中的每个元素
do $$
declare
x int;
beginforeach x in array (array[[1,2,3],[4,5,6]]) loopraise notice 'x = %', x;end loop;
end $$;
do $$
declare
x int[];
begin
-- 如果指定了一个正整数的 SLICE,FOREACH 将会变量数组的切片;SLICE 不能大于数组的维度。foreach x slice 1 in array (array[[1,2,3],[4,5,6]]) loopraise notice 'x = %', x;end loop;
end $$;
游标
PL/pgSQL 游标允许我们封装一个查询,然后每次处理结果集中的一条记录。游标可以将大
结果集拆分成许多小的记录,避免内存溢出;另外,我们可以定义一个返回游标引用的函数,然
后调用程序可以基于这个引用处理返回的结果集
使用游标的步骤大体如下:
- 声明游标变量
- 打开游标
- 从游标中获取结果
- 判断是否存在更多结果。如果存在,执行第 3 步;否则,执行第 5 步;
- 关闭游标
do $$
declare
-- 声明变量类型为recordemp record;emp_cur cursor for select * from employees limit 10;
begin
-- 打开游标open emp_cur;loop-- 获取 fetchfetch emp_cur into emp;-- 退出循环条件 when not found 没有找到数据exit when not found ;raise notice '员工信息:% ,%',emp.first_name,emp.last_name;end loop;-- 关闭游标close emp_cur;
end $$;
游标传参
do $$
declare
-- 声明变量类型为recordemp record;emp_cur cursor(dept_id integer) for select * from employees where department_id = dept_id limit 10;
begin
-- 打开游标open emp_cur(90);loop-- 获取 fetchfetch emp_cur into emp;-- 退出循环条件 when not found 没有找到数据exit when not found ;raise notice '员工信息:% ,%',emp.first_name,emp.last_name;end loop;-- 关闭游标close emp_cur;
end $$;
声明了一个游标 emp_cur,并且绑定了一个查询语句,通过一个参数 dept_id 获取指
定部门的员工;然后使用 open 打开游标;接着在循环中使用 fetch 语句获取游标中的记录,
如果没有找到更多数据退出循环语句;变量 emp 用于存储游标中的记录;最后使用 close
语句关闭游标,释放资源
官网介绍
错误处理
报告错误和信息
PL/pgSQL 提供了 RAISE 语句,用于打印消息或者抛出错误:
RAISE level format;
不同的 level 代表了错误的不同严重级别,包括:
- DEBUG
- LOG
- NOTICE
- INFO
- WARNING
- EXCEPTION
,我们经常使用 NOTICE 输出一些信息。如果不指定 level,默认为 EXCEPTION,
将会抛出异常并且终止代码运行
format 是一个用于提供信息内容的字符串,可以使用百分号(%)占位符接收参数的值, 两
个连写的百分号(%%)表示输出百分号自身
DO $$
BEGINRAISE DEBUG 'This is a debug text.';RAISE INFO 'This is an information.';RAISE LOG 'This is a log.';RAISE WARNING 'This is a warning at %', now();RAISE NOTICE 'This is a notice %%';
END $$;
从结果可以看出,并非所有的消息都会打印到客户端和服务器日志中。这个可以通过配置参
数 client_min_messages和 log_min_messages 进行设置。
对于 EXCEPTION 级别的错误,可以支持额外的选项:
RAISE [ EXCEPTION ] format USING option = expression [, ... ];
RAISE [ EXCEPTION ] condition_name USING option = expression [, ... ];
RAISE [ EXCEPTION ] SQLSTATE 'sqlstate' USING option = expression [, ... ];
RAISE [ EXCEPTION ] USING option = expression [, ... ];
其中,option 可以是以下选项:
- MESSAGE,设置错误消息。如果 RAISE 语句中已经包含了 format 字符串,不能再使用该选项。
- DETAIL,指定错误详细信息。
- HINT,设置一个提示信息
- ERRCODE,指定一个错误码(SQLSTATE)。可以是文档中的条件名称或者五个字符组成的SQLSTATE 代码。
- COLUMN、CONSTRAINT、DATATYPE、TABLE、SCHEMA,返回相关对象的名称。
do $$
beginraise info 'This s an info.';raise debug 'This s an debug.';raise warning 'This s an warning.';
end $$;
检查断言
PL/pgSQL 提供了 ASSERT 语句,用于调试存储过程和函数:
ASSERT condition [ , message ];
其中,condition 是一个布尔表达式;如果它的结果为真,ASSERT 通过;如果结果为假或者
NULL,将会抛出 ASSERT_FAILURE 异常。message 用于提供额外的错误信息,默认为“assertion
failed”。例如
DO $$
DECLAREi integer := 1;
BEGINASSERT i = 0, 'i 的初始值应该为 0!';
END $$;
ASSERT 只适用于代码调试;输出错误信息使用 RAISE 语句。
捕获异常
默认情况下,PL/pgSQL 遇到错误时会终止代码执行,同时撤销事务。我们也可以在代码块
中使用 EXCEPTION 捕获错误并继续事务
[ <<label>> ]
[ DECLAREdeclarations ]
BEGINstatements
EXCEPTIONWHEN condition [ OR condition ... ] THENhandler_statements[ WHEN condition [ OR condition ... ] THENhandler_statements... ]
END;
如果代码执行出错,程序将会进入 EXCEPTION 模块;依次匹配 condition,找到第一个匹
配的分支并执行相应的 handler_statements;如果没有找到任何匹配的分支,继续抛出错误
DO $$
DECLAREi integer := 1;
BEGINi := i / 0;
EXCEPTIONWHEN division_by_zero THENRAISE NOTICE '除零错误!';WHEN OTHERS THENRAISE NOTICE '其他错误!';
END $$;
OTHERS 用于捕获未指定的错误类型。
PL/pgSQL 还提供了捕获详细错误信息的 GET STACKED DIAGNOSTICS 语句,具体可以参
考官方文档
自定义函数
创建一个自定义的 PL/pgSQL 函数,可以使用 CREATE FUNCTION 语句
CREATE [ OR REPLACE ] FUNCTIONname ( [ [ argmode ] [ argname ] argtype [ { DEFAULT | = } default_expr ]
[, ...] ] )RETURNS rettype
AS $$
DECLAREdeclarations
BEGINstatements;...
END; $$
LANGUAGE plpgsql;
CREATE 表示创建函数,
OR REPLACE 表示替换函数定义;
name 是函数名;括号内是参数,多个参数使用逗号分隔;
argmode 可以是 IN(输入)、OUT(输出)、
INOUT(输入输出)或者 VARIADIC(数量可变),默认为 IN;
argname 是参数名称;argtype 是参数的类型;
default_expr是参数的默认值;rettype 是返回数据的类型;
AS 后面是函数的定义,和上文中的匿名块相同;
最后,LANGUAGE 指定函数实现的语言,也可以是其他过程语言
-- 函数创建
create or replace function get_emp_count(p_deptid integer)
returns integer
as $$
declare ln_count integer;
begin if p_deptid <= 0 thenraise exception '部门编号不能小于等于0!p_deptid:%',p_deptid;end if;select count(*) into ln_countfrom employeeswhere department_id = p_deptid; return ln_count;
end $$
language plpgsql;
-- 函数使用
select get_emp_count(90) as total;
select get_emp_count(-1) as total;
重载
PL/pgSQL 函数支持重载(Overloading),也就是相同的函数名具有不同的函数参数
CREATE OR REPLACE FUNCTION public.get_emp_count(p_deptid integer,p_hire_date varchar)RETURNS integerLANGUAGE plpgsql
AS $function$
declare ln_count integer;
begin if p_deptid <= 0 thenraise exception '部门编号不能小于等于0!p_deptid:%',p_deptid;end if;select count(*) into ln_countfrom employeeswhere department_id = p_deptidand hire_date > p_hire_date;return ln_count;
end $function$
;
VARIADIC
VARIADIC:参数的数量是多个,可变的
-- 数组 nums的下标索引的产生,1维数组
-- generate_subscripts(nums,1)
create or replace function sum_num(variadic nums numeric[])
returns numeric
as $$
declare total numeric;
begin select sum(nums[i]) into total-- t(i)返回的下标索引变量为ifrom generate_subscripts(nums,1) t(i);return total;
end $$
language plpgsql;
-- 数组内元素为1和2的和
-- 参数 nums 是一个数组,可以传入任意多个参数;然后计算它们的和值
select sum_num(1,2);
存储过程
PostgreSQL 11 增加了存储过程,使用 CREATE PROCEDURE 语句创建:
CREATE [ OR REPLACE ] PROCEDUREname ( [ [ argmode ] [ argname ] argtype [ { DEFAULT | = } default_expr ]
[, ...] ] )
AS $$
DECLAREdeclarations
BEGINstatements;...
END; $$
LANGUAGE plpgsql;
-- 调用存储过程
call 过程名(参数1,参数2...);
示例
create or replace procedure transfer(p_from integer,p_to integer,p_amount numeric)
as $$
declare l_count integer;
begin select count(*) into l_countfrom accountswhere id = p_from;if l_count = 0 thenraise exception '原账户不存在:%',p_from;end if;select count(*) into l_countfrom accountswhere id = p_to;if l_count = 0 thenraise exception '目标账户不存在:%',p_to;end if;if p_amount < 0 thenraise exception '转账金额错误:%',p_amount;end if;-- 1.扣款update accounts set balance = balance - p_amountwhere id = p_from;-- 2.存款update accounts set balance = balance + p_amountwhere id = p_to;-- 3.记录流水
end $$
language plpgsql;
-- 调用存储过程
call public.transfer(1,2,3000);select * from public.accounts a ;
事务管理
在存储过程内部,可以使用 COMMIT 或者 ROLLBACK 语句提交或者回滚事务
create table test2(col integer);
-- 创建存储过程
create or replace procedure transaction_test()
as $$
begin for i in 0..10 loopinsert into test2 values(i);--mod 求余-- 偶数提交if mod(i,2) = 0 thencommit;else-- 奇数回滚rollback;end if;end loop;end $$
language plpgsql;
-- 调用存储过程
call transaction_test();
select * from test2;
相关文章:

postgresql-存储过程
postgresql-存储过程 简述PL/pgSQL 代码块结构示例嵌套子块 声明与赋值控制结构IF 语句CASE 语句简单case语句搜索 CASE 语句 循环语句continuewhilefor语句遍历查询结果 foreach 游标游标传参 错误处理报告错误和信息检查断言 捕获异常自定义函数重载VARIADIC 存储过程示例事务…...
改造user ,使得userId相同视为一个对象,user是Key,User的username做value
如果您想要将具有相同userId的用户视为一个对象,其中User对象是键,而User对象的username是值,您可以使用Java的Map<User, String>数据结构来实现。以下是示例代码: java import java.util.*;class User {private int userI…...

力扣刷题-数组-滑动窗口法相关题目总结
209. 长度最小的子数组(最小滑窗) 给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的 连续 子数组,并返回其长度。如果不存在符合条件的子数组,返回 0。 示例: 输入&…...

Qt创建线程(线程池)
1.线程池可以创建线程统一的管理线程(统一创建、释放线程) 2.使用线程池方法实现点击开始按钮生成10000个随机数,然后分别使用冒泡排序和快速排序排序这10000个随机数,最后在窗口显示排序后的数字: mainwindow.h文件…...
【Java】泛型 之 使用泛型
使用ArrayList时,如果不定义泛型类型时,泛型类型实际上就是 Object: // 编译器警告: List list new ArrayList(); list.add("Hello"); list.add("World"); String first (String) list.get(0); String second (Strin…...
消费者NPS调查,帮您了解客户满意度!
随着市场竞争的日益激烈,了解消费者需求和对企业品牌的认知程度,对于企业的持续发展至关重要。您的客户对您的产品或服务有多满意?您是否想提升客户忠诚度,从而增加业务的持续增长?群狼调研(长沙产品包装测试)为您提供全新的消费者NPS调查服…...

Webpack监视文件修改,自动重新打包文件
方法一:使用watch监视文件变化 在终端中输入以下指令: npx webpack --watch 我们使用这种方法监听文件变化时只会监听我们计算机本地的文件变化,在开发场景中我们的项目是要部署到服务器中的,因此这种方式并不推荐。 方法二&…...

list容器排序案例
案例描述:将Perspn自定义数据类型进行排序,Person中属性有姓名、年龄、身高 排序规则:按照年龄进行升序,如果年龄相同按照身高进行降序 代码示例 #include <iostream> #include <string.h> #include <iterator> #include <vector…...

PHP使用Analysis中英文分词
1、下载Analysis,创建test.php测试 2、引入Analysis实现中文分词 <?php include "./Analysis/Analysis.php";$annew \WordAnalysis\Analysis(); $content"机器学习是一门重要的技术,可以用于数据分析和模式识别。"; //10分词数…...

视频汇聚/视频云存储/视频监控管理平台EasyCVR录像存储功能如何优化?具体步骤是什么?
视频云存储/安防监控EasyCVR视频汇聚平台基于云边端智能协同,支持海量视频的轻量化接入与汇聚、转码与处理、全网智能分发、视频集中存储等。视频监控系统EasyCVR拓展性强,视频能力丰富,具体可实现视频监控直播、视频轮播、视频录像、云存储、…...

Web服务(Web Service)
简介 Web服务(Web Service)是一种Web应用开发技术,用XML描述、发布、发现Web服务。它可以跨平台、进行分布式部署。 Web服务包含了一套标准,例如SOAP、WSDL、UDDI,定义了应用程序如何在Web上实现互操作。 Web服务的服…...
Java第4章 类的继承
目录 内容说明 章节内容 一、继承的概念 二、继承的使用 extends关键字...
Linux网络和安全:配置、远程访问与防御指南
文章目录 Linux 网络和安全引言网络配置IP地址配置配置网络接口防火墙设置安全性加强 Linux网络配置及端口管理网络配置命令端口管理 防火墙和安全性设置防火墙管理工具安全性设置 Linux远程访问技术:SSH和VPNSSHVPN Linux软件和服务网络工具文件传输VPN技术安全审计…...

如何搭建Linux环境
W...Y的主页 😊 代码仓库分享 💕 当我们想要搭建一个Linux系统,我们应该怎么使用呢? 今天我就带领大家搭建Linux系统!!! 目录 Linux环境安装 双系统(不推荐) poww…...

【解决方案】edge浏览器批量添加到集锦功能消失的解决方案
edge的集锦功能很好用,右键标签页会出现如下选项: 但在某次edge更新后,右键标签页不再出现该选项: 这里可以参考为什么我的Edge浏览器右键标签页没有“将所有标签页添加到集锦”功能? - Microsoft Community 一文提出…...
JS操作字符串方法学习系列(1)-每天学习10个方法
目录 **字符串连接 (Concatenation)**:**字符串长度 (Length)**:**字符串查找 (Search)**:**字符串替换 (Replace)**:**字符串分割 (Split)**:**字符串大小写转换 (Case Conversion)**:**字符串切片 (Slice)**:**字符串删除空白 (Trim)**:**字符串检查开头和结尾 (Starts/EndsW…...

iterator和generator
iterator和generator iterator es6: let/const ...展开 迭代器 是一种机制,比如在控制台输出Iterator是没有这个类的,为不同的数据结构提供迭代循环的机制。 迭代器对象:具备next方法,next能够对你指定的数据进行迭代循环&#x…...
ipv6笔记及总结
1、路由器请求消息Router Solicitation和路由器通告Router Advertisement消息主要用于无状态地址的情况下,有状态的情况使用的是dhcpv6 server分配(例如:IPv6地址以及其他信息(DNS、域名等))。 2、关于IPv…...

64位Ubuntu20.04.5 LTS系统安装32位运行库
背景: 在ubutu(版本为20.04.5 LTS)中运行./arm-none-linux-gnueabi-gcc -v 后提示“no such device”。 经多方查证,是ubutu的版本是64位的,而需要运行的编译工具链是32位的,因此会不兼容。 解决方法就是在…...
关于vue.config.js
关于vue.config.js 简述 vue.config.js是一个可选的配置文件,如果项目的根目录中存在这个文件,那么它就会被vue/cli-service自动加载。你也可以使用package.json中的vue字段,但是注意这种写法需要你严格遵守JSON的格式来写。 这个文件应该…...
Oracle查询表空间大小
1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...

MFC内存泄露
1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...
STM32+rt-thread判断是否联网
一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...

使用分级同态加密防御梯度泄漏
抽象 联邦学习 (FL) 支持跨分布式客户端进行协作模型训练,而无需共享原始数据,这使其成为在互联和自动驾驶汽车 (CAV) 等领域保护隐私的机器学习的一种很有前途的方法。然而,最近的研究表明&…...

新能源汽车智慧充电桩管理方案:新能源充电桩散热问题及消防安全监管方案
随着新能源汽车的快速普及,充电桩作为核心配套设施,其安全性与可靠性备受关注。然而,在高温、高负荷运行环境下,充电桩的散热问题与消防安全隐患日益凸显,成为制约行业发展的关键瓶颈。 如何通过智慧化管理手段优化散…...

安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖
在Vuzix M400 AR智能眼镜的助力下,卢森堡罗伯特舒曼医院(the Robert Schuman Hospitals, HRS)凭借在无菌制剂生产流程中引入增强现实技术(AR)创新项目,荣获了2024年6月7日由卢森堡医院药剂师协会࿰…...
tomcat入门
1 tomcat 是什么 apache开发的web服务器可以为java web程序提供运行环境tomcat是一款高效,稳定,易于使用的web服务器tomcathttp服务器Servlet服务器 2 tomcat 目录介绍 -bin #存放tomcat的脚本 -conf #存放tomcat的配置文件 ---catalina.policy #to…...
DiscuzX3.5发帖json api
参考文章:PHP实现独立Discuz站外发帖(直连操作数据库)_discuz 发帖api-CSDN博客 简单改造了一下,适配我自己的需求 有一个站点存在多个采集站,我想通过主站拿标题,采集站拿内容 使用到的sql如下 CREATE TABLE pre_forum_post_…...

企业大模型服务合规指南:深度解析备案与登记制度
伴随AI技术的爆炸式发展,尤其是大模型(LLM)在各行各业的深度应用和整合,企业利用AI技术提升效率、创新服务的步伐不断加快。无论是像DeepSeek这样的前沿技术提供者,还是积极拥抱AI转型的传统企业,在面向公众…...

【51单片机】4. 模块化编程与LCD1602Debug
1. 什么是模块化编程 传统编程会将所有函数放在main.c中,如果使用的模块多,一个文件内会有很多代码,不利于组织和管理 模块化编程则是将各个模块的代码放在不同的.c文件里,在.h文件里提供外部可调用函数声明,其他.c文…...