当前位置: 首页 > news >正文

Oracle数据库数据编程SQL<3.7 PL/SQL 触发器(Trigger)>

触发器是Oracle数据库中的一种特殊存储过程,它会在特定数据库事件发生时自动执行。触发器通常用于实现复杂的业务规则、数据验证、审计跟踪等功能。

目录

一、触发器基本概念

1. 触发器特点

2. 触发器组成要素

二、触发器类型

1. DML触发器

2. DDL触发器

3. 系统/数据库事件触发器

4. INSTEAD OF触发器

三、创建DML触发器

1. 基本语法

2. 行级触发器示例

3. 语句级触发器示例

四、特殊触发器

1. 复合触发器(11g+)

2. INSTEAD OF触发器(用于视图)

3. 系统事件触发器

五、触发器中的特殊变量和函数

1. OLD 和 NEW 伪记录

2. 事件属性函数

3. 条件谓词

4. 简单示例

5. 简单练习

六、触发器管理

1. 查看触发器

2. 启用/禁用触发器

3. 重新编译触发器

4. 删除触发器

七、触发器最佳实践

八、常见问题解决方案

1. 避免触发器递归

2. 处理大批量操作

3. 跨数据库同步

九、触发器使用注意事项


一、触发器基本概念

触发器在数据库里以独立的对象存储,他与存储过程不同的是,存储过程通过其他程序来启动运行或者直接运行,而触发器是由一个事件来启动运行。即触发器是当某个事件发生时自动地隐式运行,并且触发器不接收参数。 

1. 触发器特点

  • 自动执行:满足条件时由数据库自动触发

  • 事件驱动:响应特定DML或DDL操作

  • 无显式调用:不能像存储过程那样直接调用

  • 事务感知:作为触发语句的一部分执行

2. 触发器组成要素

  • 触发事件:INSERT、UPDATE、DELETE等DML操作

  • 触发时机:BEFORE或AFTER

  • 触发级别:行级(FOR EACH ROW)或语句级

  • 触发条件:WHEN子句定义的条件

  • 触发体:PL/SQL代码块

二、触发器类型

1. DML触发器

响应数据操作语言(DML)事件:

  • INSERT

  • UPDATE

  • DELETE

  • MERGE (10g+)

2. DDL触发器

响应数据定义语言(DDL)事件:

  • CREATE

  • ALTER

  • DROP

  • TRUNCATE等

3. 系统/数据库事件触发器

响应数据库系统事件:

  • 登录/注销(LOGON/LOGOFF)

  • 服务器错误(SERVERERROR)

  • 启动/关闭(STARTUP/SHUTDOWN)

4. INSTEAD OF触发器

用于视图上的DML操作

三、创建DML触发器

语句级触发器(statement):当某触发事件发生时,该触发器执行一次

行级触发器(row):当某触发事件发生时,受到影响的每一行数据,触发器都单独执行一次

1. 基本语法

CREATE [OR REPLACE] TRIGGER trigger_name
{BEFORE | AFTER | INSTEAD OF}
{INSERT | UPDATE | DELETE [OR INSERT | UPDATE | DELETE...]}
ON {table_name | view_name}
[REFERENCING [OLD AS old] [NEW AS new]]
[FOR EACH ROW]
[WHEN (condition)]
[DECLAREdeclaration_statements]
BEGINexecutable_statements
[EXCEPTIONexception_handling_statements]
END [trigger_name];--化说明
create or replace trigger tri_name--创建触发器
{before/after}--触发的时间点{DML操作} on 表名
{for each row}--加上是行级触发,不加是语句级
{when 条件}
begin
{referencing {OLD {as} old|new {as} NEW}new PARENT as parent}---触发器的执行部分
end;
/-- 简单示例1
create or replace trigger tr_1before delete on emp11
begininsert into emp12(ename)select ename from emp where empno = 7369;
end;
/
-- 简单示例2
--创建一个触发器 当删除emp1表中的数据时,向emp2插入7788的员工信息
--并且删除emp3中7788的信息。
-- 准备
create table emp1 as select * from emp;
create table emp2 as select * from emp;
create table emp3 as select * from emp;
-- 创建触发器
create or replace trigger tr_1before delete on emp1
begininsert into emp2(ename, sal)select ename, sal from emp where empno = 7788;delete from emp3 where empno = 7788;
end;
/
-- 触发
delete from emp1 where empno=7788;

2. 行级触发器示例

-- 薪资变更审计触发器
CREATE OR REPLACE TRIGGER audit_salary_change
BEFORE UPDATE OF salary ON employees
FOR EACH ROW
WHEN (NEW.salary <> OLD.salary)
DECLAREv_change_type VARCHAR2(10);
BEGIN-- 确定变更类型IF :NEW.salary > :OLD.salary THENv_change_type := 'RAISE';ELSEv_change_type := 'CUT';END IF;-- 记录审计信息INSERT INTO salary_audit (audit_id, employee_id, old_salary, new_salary,change_type, change_date, changed_by) VALUES (audit_seq.NEXTVAL, :NEW.employee_id,:OLD.salary, :NEW.salary,v_change_type, SYSDATE, USER);
END audit_salary_change;
/

3. 语句级触发器示例

-- 限制非工作时间操作
CREATE OR REPLACE TRIGGER restrict_after_hours_dml
BEFORE INSERT OR UPDATE OR DELETE ON employees
DECLAREv_current_time VARCHAR2(8) := TO_CHAR(SYSDATE, 'HH24:MI:SS');v_day_of_week VARCHAR2(3) := TO_CHAR(SYSDATE, 'DY');
BEGIN-- 工作日晚上8点到早上6点禁止操作IF v_day_of_week NOT IN ('SAT', 'SUN') AND (v_current_time > '20:00:00' OR v_current_time < '06:00:00') THENRAISE_APPLICATION_ERROR(-20001, '非工作时间(工作日6:00-20:00)不允许修改员工数据');END IF;
END restrict_after_hours_dml;
/

四、特殊触发器

1. 复合触发器(11g+)

CREATE OR REPLACE TRIGGER compound_emp_trigger
FOR INSERT OR UPDATE OR DELETE ON employees
COMPOUND TRIGGER-- 在触发语句开始前执行BEFORE STATEMENT ISBEGINDBMS_OUTPUT.PUT_LINE('开始员工数据变更操作');END BEFORE STATEMENT;-- 每行变更前执行BEFORE EACH ROW ISBEGINDBMS_OUTPUT.PUT_LINE('准备变更员工ID: ' || NVL(:NEW.employee_id, :OLD.employee_id));END BEFORE EACH ROW;-- 每行变更后执行AFTER EACH ROW ISBEGINDBMS_OUTPUT.PUT_LINE('已完成变更员工ID: ' || NVL(:NEW.employee_id, :OLD.employee_id));END AFTER EACH ROW;-- 在触发语句结束后执行AFTER STATEMENT ISBEGINDBMS_OUTPUT.PUT_LINE('员工数据变更操作完成');END AFTER STATEMENT;
END compound_emp_trigger;
/

2. INSTEAD OF触发器(用于视图)

-- 创建复杂视图
CREATE OR REPLACE VIEW emp_dept_view AS
SELECT e.employee_id, e.last_name, e.salary, d.department_id, d.department_name
FROM employees e JOIN departments d 
ON e.department_id = d.department_id;-- 创建INSTEAD OF触发器支持插入
CREATE OR REPLACE TRIGGER io_emp_dept_insert
INSTEAD OF INSERT ON emp_dept_view
FOR EACH ROW
DECLAREv_dept_id NUMBER;
BEGIN-- 检查部门是否存在BEGINSELECT department_id INTO v_dept_idFROM departmentsWHERE department_name = :NEW.department_name;EXCEPTIONWHEN NO_DATA_FOUND THENRAISE_APPLICATION_ERROR(-20001, '部门 ' || :NEW.department_name || ' 不存在');END;-- 插入员工记录INSERT INTO employees (employee_id, last_name, salary, department_id) VALUES (employees_seq.NEXTVAL, :NEW.last_name, :NEW.salary, v_dept_id);
END io_emp_dept_insert;
/

3. 系统事件触发器

-- 登录审计触发器
CREATE OR REPLACE TRIGGER logon_audit_trigger
AFTER LOGON ON DATABASE
BEGININSERT INTO logon_audit (audit_id, username, logon_time, host, ip_address) VALUES (logon_seq.NEXTVAL, USER,SYSDATE, SYS_CONTEXT('USERENV', 'HOST'),SYS_CONTEXT('USERENV', 'IP_ADDRESS'));
END logon_audit_trigger;
/-- DDL变更审计触发器
CREATE OR REPLACE TRIGGER audit_ddl_changes
AFTER DDL ON SCHEMA
BEGININSERT INTO ddl_audit (audit_id, username, event_type, object_type,object_name, change_date) VALUES (ddl_audit_seq.NEXTVAL, USER,ORA_SYSEVENT, ORA_DICT_OBJ_TYPE,ORA_DICT_OBJ_NAME, SYSDATE);
END audit_ddl_changes;
/

五、触发器中的特殊变量和函数

1. OLD 和 NEW 伪记录

  • :OLD:引用操作前的行值(UPDATE/DELETE)---old.列名:此列中的旧值

  • :NEW:引用操作后的行值(INSERT/UPDATE)---new.列名:此列中的新值

2. 事件属性函数

  • ORA_SYSEVENT:触发事件的名称

  • ORA_DICT_OBJ_TYPE:DDL操作的对象类型

  • ORA_DICT_OBJ_NAME:DDL操作的对象名称

  • ORA_IS_ALTER_COLUMN:检查是否修改了特定列

3. 条件谓词

  • INSERTING:触发器由INSERT触发时为TRUE

  • UPDATING:触发器由UPDATE触发时为TRUE

  • DELETING:触发器由DELETE触发时为TRUE

条件谓语

old

new

update

delete

null

insert

null

4. 简单示例

--创建一个触发器
--当emp1被更新是,将更新前和更新后的ename和empno插入到emp2
--的对应列,在job列显示更新前还是更新后,并且hiredate列插入更新时间
CREATE OR REPLACE TRIGGER TRE_1BEFORE UPDATE ON EMP1FOR EACH ROW
BEGININSERT INTO EMP2 (ENAME, EMPNO,job,hiredate) VALUES (:old.ename,:old.empno,'更新前',sysdate);INSERT INTO EMP2 (ENAME, EMPNO,job,hiredate) VALUES (:new.ename,:new.empno,'更新后',SYSDATE);
END;TRUNCATE TABLE emp2
UPDATE emp1 SET sal=sal+10000;
SELECT * FROM emp2
特性INSERTUPDATEDELETE
OLDNULL实际值实际值
NEW实际值实际值NULL

5. 简单练习

--创建一张emp1和emp内容一样。创建emp2只保留emp的格式。
--创建一个触发器
--当emp1表被更新时触发,将更新前和更新后的ename,empno插入到emp2中
-- 创建触发器
create or replace trigger tr_3
before update on emp1
for each rowbegininsert into emp2 (ename,empno,job) values(:old.ename,:old.empno,'old');insert into emp2 (ename,empno,job) values(:new.ename,:new.empno,'new');
end;
/
-- 触发
update emp1 set empno=empno-7000,ename=lower(ename);
-- 查询验证变化
select * from emp1;
select * from emp2;

六、触发器管理

1. 查看触发器

-- 查看触发器定义
SELECT trigger_name, trigger_type, triggering_event, table_name, status
FROM user_triggers;-- 查看触发器源代码
SELECT text FROM user_source 
WHERE name = 'AUDIT_SALARY_CHANGE' AND type = 'TRIGGER'
ORDER BY line;

2. 启用/禁用触发器

-- 禁用单个触发器
ALTER TRIGGER audit_salary_change DISABLE;-- 启用单个触发器
ALTER TRIGGER audit_salary_change ENABLE;-- 禁用表上的所有触发器
ALTER TABLE employees DISABLE ALL TRIGGERS;-- 启用表上的所有触发器
ALTER TABLE employees ENABLE ALL TRIGGERS;

3. 重新编译触发器

ALTER TRIGGER trigger_name COMPILE;

4. 删除触发器

DROP TRIGGER trigger_name;

七、触发器最佳实践

  1. 保持简洁:触发器应简短高效,避免复杂业务逻辑

  2. 避免递归:注意触发器可能导致的级联触发

  3. 考虑性能:行级触发器对大批量操作影响较大

  4. 明确文档:记录触发器目的和业务规则

  5. 异常处理:妥善处理可能出现的错误

  6. 避免事务控制:通常不应在触发器中提交或回滚

  7. 测试充分:验证触发器在各种场景下的行为

八、常见问题解决方案

1. 避免触发器递归

CREATE OR REPLACE TRIGGER prevent_recursion
BEFORE UPDATE ON employees
FOR EACH ROW
DECLAREv_recursion_flag BOOLEAN := FALSE;
BEGIN-- 检查是否由触发器调用IF UPDATING AND DBMS_UTILITY.FORMAT_CALL_STACK LIKE '%PREVENT_RECURSION%' THENv_recursion_flag := TRUE;END IF;-- 如果不是递归调用,则执行业务逻辑IF NOT v_recursion_flag THEN-- 业务逻辑代码END IF;
END;
/

2. 处理大批量操作

-- 使用BULK COLLECT和FORALL优化
CREATE OR REPLACE TRIGGER optimize_bulk_operation
AFTER INSERT ON large_table
DECLARETYPE id_array IS TABLE OF large_table.id%TYPE;v_ids id_array;
BEGIN-- 批量收集新插入的IDSELECT id BULK COLLECT INTO v_idsFROM large_tableWHERE status = 'NEW';-- 批量处理FORALL i IN 1..v_ids.COUNTUPDATE related_tableSET last_updated = SYSDATEWHERE large_table_id = v_ids(i);
END;
/

3. 跨数据库同步

CREATE OR REPLACE TRIGGER sync_cross_database
AFTER INSERT OR UPDATE OR DELETE ON local_table
FOR EACH ROW
DECLAREPRAGMA AUTONOMOUS_TRANSACTION;
BEGINIF INSERTING THENINSERT INTO remote_table@remote_db VALUES (:NEW.id, :NEW.name);ELSIF UPDATING THENUPDATE remote_table@remote_dbSET name = :NEW.nameWHERE id = :OLD.id;ELSIF DELETING THENDELETE FROM remote_table@remote_db WHERE id = :OLD.id;END IF;COMMIT;
EXCEPTIONWHEN OTHERS THENROLLBACK;-- 记录错误但不中断主事务INSERT INTO error_log VALUES (SYSDATE, 'sync_cross_database', SQLERRM);COMMIT;
END;
/

九、触发器使用注意事项

编写触发器时,需要注意一下几点:

(1)触发器不接受参数

(2)一个表上最多可有12个触发器,但同一时间、同一事件、同一类型的触发器只能有一个。并且各触发器之间不能有矛盾。

(3)在一个表上的触发器越多,对在该表上的DML操作的性能影响就越大

(4)触发器最大为32KB。若确实需要,可以先建立过程,然后在触发器中用CALL语句进行调用

(5)在触发器的执行部分只能用DML语句(SELECT、INSERT、UDATE、DELETE),不能使用DDL语句(CREATE、ALTER、DROP)

(6)触发器中不能包含事物控制语句(COMMIT、ROLLBACK、SAVEPOINT)。因为触发器是触发语句的一部分,触发语句被提交、回退时,触发器也被提交、回退了。

(7)在触发器主体中调用的任何过程、函数,都不能使用事务控制语句

(8)在触发器主体中不能声明任何Long和Blob变量。新值new和旧值old也不能向表中的任何Long和Blob列。

(9)不同类型的触发器(如DML触发器、INSTEAD OF触发器、系统触发器)的语法格式和作用有比较大区别

触发器是Oracle数据库强大的功能,合理使用可以实现复杂的业务规则、数据完整性和审计需求。但也需谨慎使用,避免过度依赖触发器导致系统难以维护。

相关文章:

Oracle数据库数据编程SQL<3.7 PL/SQL 触发器(Trigger)>

触发器是Oracle数据库中的一种特殊存储过程&#xff0c;它会在特定数据库事件发生时自动执行。触发器通常用于实现复杂的业务规则、数据验证、审计跟踪等功能。 目录 一、触发器基本概念 1. 触发器特点 2. 触发器组成要素 二、触发器类型 1. DML触发器 2. DDL触发器 3.…...

反常积分和定积分的应用 1

网课 还是得跟上网课的进度。但是不要给自己太大的压力。看到数学题确实有点慌张。老师为什么说写对了不要打对号&#xff0c;我感觉打对号可以给自己充足的正反馈。关键问题就是能做对的题不多。这篇笔记主要整理网课的一些笔记。网课落下的比较多&#xff0c;大概还需要补好…...

Day49 | 11. 盛最多水的容器、16. 最接近的三数之和、33. 搜索旋转排序数组、36. 有效的数独

11. 盛最多水的容器 题目链接&#xff1a;11. 盛最多水的容器 - 力扣&#xff08;LeetCode&#xff09; 题目难度&#xff1a;中等 代码&#xff1a; class Solution {public int maxArea(int[] height) {int i0,jheight.length-1,res0;while(i<j){resheight[i]<heig…...

31天Python入门——第20天:魔法方法详解

你好&#xff0c;我是安然无虞。 文章目录 魔法方法1. __new__和__del__2. __repr__和__len__3. __enter__和__exit__4. 可迭代对象和迭代器5. 中括号[]数据操作6. __getattr__、__setattr__ 和 __delattr__7. 可调用的8. 运算符 魔法方法 魔法方法: Python中的魔法方法是一类…...

WPF 浅述IsHitTestVisible属性

WPF 浅述IsHitTestVisible属性 IsHitTestVisible 属性是 WPF 中一个非常重要的属性&#xff0c;它决定了一个控件是否可以作为 hit test 的一部分被检测到。理解这个属性对于处理交互事件&#xff08;如鼠标点击、触摸等&#xff09;非常重要。 IsHitTestVisible 属性的含义&am…...

WSN 经典定位算法

WSN 经典定位算法 包括&#xff1a; Centoid, Bounding_box, Grid_Scan, RSSI, DV_hop, MDS_MAP&#xff0c;APIT-WSN Localization/Amorphous/Amorphous.m , 3351 Localization/APIT/APIT.m , 4169 Localization/APIT/PPIT.m , 3889 Localization/Bounding Box/Bounding_Box.…...

LLM 优化技术(1)——Scaled-Dot-Product-Attention(SDPA)

在 Transformer 中抛弃了传统的 CNN 和 RNN&#xff0c;整个网络结构完全由Scaled Dot Product Attention 和Feed Forward Neural Network组成。一个基于 Transformer 的可训练的神经网络可以通过堆叠 Transformer 的形式进行搭建&#xff0c;Attention is All You Need论文中通…...

【深度学习】嘿马深度学习目标检测教程第1篇:商品目标检测要求、目标,1.1 项目演示【附代码文档】

教程总体简介&#xff1a;要求 目标 1.1 项目演示 学习目标 1.1 图像识别背景 1.2 什么是目标检测 1.2.1 目标检测定义 1.2.1.1 物体 1.3 目标检测应用场景 1.3.1 行业 1.3.2 应用类别 1.4 开发环境搭建 目标检测概述 3.1 目标检测任务描述 3.1.4 目标定位的简单实现 项目实现 …...

【蓝桥杯】单片机设计与开发,RTC实时时钟

一、RTC-DS1302概述 二、BCD码 三、三线协议概述 四、RTC的应用 五、DS1302的驱动函数 六、操作流程 七、三线协议驱动程序...

Java 各版本的新特性

Java 各版本的新特性主要集中在提升开发效率、性能优化、语言功能增强和模块化支持等方面。以下是 JDK 8 到 JDK 21&#xff08;截至2023年&#xff09;的主要新特性概览&#xff1a; JDK 8 (2014) - LTS Lambda 表达式&#xff1a;支持函数式编程&#xff0c;简化匿名内部类。…...

OpenGL中EBO的使用及原理

EBO 是什么&#xff1f; 在OpenGL中&#xff0c;EBO&#xff08;Element Buffer Object&#xff09;&#xff0c;也称为索引缓冲对象 IBO&#xff08;Index Buffer Object&#xff09;&#xff0c;是一种用于存储顶点索引数据的缓冲区对象。它的核心作用是通过复用顶点数据来减…...

应用分享 | AWG技术突破:操控钻石氮空位色心,开启量子计算新篇章!

利用AWG操作钻石中的氮空位色彩中心 金刚石中的颜色中心是晶格中的缺陷&#xff0c;其中碳原子被不同种类的原子取代&#xff0c;而相邻的晶格位点则是空的。由于色心具有明亮的单光子发射和光学可触及的自旋&#xff0c;因此有望成为未来量子信息处理和量子网络的固态量子发射…...

【Ultralytics YOLO COCO 评估脚本 | 获得COCO评价指标】

文章目录 Ultralytics YOLO COCO 评估脚本 (coco_evaluate.py)1. 描述2. 依赖项3. 使用方法4. 输入文件格式5. 输出6. 注意7. 完整代码 Ultralytics YOLO COCO 评估脚本 (coco_evaluate.py) 这是一个 Python 脚本&#xff0c;用于评估以 COCO JSON 格式提供的目标检测结果。它…...

聊一聊,元件封装知多少?

目录 01 | 简 介 02 | 常见的无源器件封装 03 | 集成(IC)类封装 04 | 功率器件类封装 05 | 连接器类封装 06 | 总 结 01 | 简 介 由于平时工作中&#xff0c;经常需要查看封装的样式&#xff0c;以便初步规划PCB布局&#xff1b;遂萌发对常用的元件封装进行一次总结。 …...

企业需要使用防病毒系统保障数据安全的原因

数据作为企业的重要资产&#xff0c;正面临勒索病毒等极大威胁。在复杂严峻的网络安全形势下&#xff0c;企业的业务运营、数据安全和声誉遭遇诸多来自网络的挑战。2023年&#xff0c;国内发生多起严重网络安全事件&#xff0c;例如数据库漏洞导致数据泄露、钓鱼邮件窃取信息、…...

使用无人机进行露天矿运输道路分析

使用无人机进行露天矿运输道路分析 无人机正在彻底改变采矿业&#xff0c;为露天矿场的运输道路收集数据和分析提供了一种新方法。通过使用 UAS 技术&#xff0c;采矿公司可以更全面地了解道路状况&#xff0c;确定磨损区域&#xff0c;并提高安全性和效率。 本文介绍了无人机用…...

基于Vue.js网页开发相关知识:Vue-router

一、基础知识 vue-router 是 Vue.js 官方的路由管理器&#xff0c;用于实现单页面应用&#xff08;SPA&#xff09;的路由功能。以下从几个方面对 vue-router 进行详细分析&#xff1a; 1. 核心概念 路由配置 vue-router 通过定义路由配置对象来管理应用的路由。每个路由配置…...

同时使用Telnet和SSH登录思科交换机

同时使用Telnet和SSH登录思科交换机 1. 配置管理IP地址 首先&#xff0c;为交换机配置一个管理IP地址&#xff0c;以便可以通过网络进行远程管理&#xff1a; Switch(config)# interface vlan [VLAN_ID] Switch(config-if)# ip address [IP地址] [子网掩码] Switch(config-i…...

presto行转列

presto的行列转换和spark、hive一样也是通过外链语句实现的&#xff0c;只不过语法和关键子有点不同&#xff0c;如下 with tmp1 as (select 1,2,3 as a1,4,5,6 as a2 ) select * from tmp1 cross join unnest(split(tmp1.a1, ,),split(tmp1.a2, ,) ) as b(a1s,a2s) 结果如下...

App Usage v5.57 Pro版 追踪手机及应用使用情况

手机使用监控神器&#xff1a;让你的手机使用情况一目了然 现代人的生活已经离不开手机——通讯、娱乐、支付、购物…每天我们花在手机上的时间越来越多。你是否好奇&#xff1a; 每天在各个应用上花费了多少时间&#xff1f;一天中查看了多少次手机&#xff1f;哪些应用在后…...

24.3 CogView3多模态生成实战:从API调优到1024高清图像生成全解析

CogView3多模态生成实战:从API调优到1024高清图像生成全解析 CogView3 & CharGLM:多模态生成技术深度解析 关键词:CogView3 API 调用,图像生成与编辑,多模态提示工程,GLM 技术栈集成,参数优化策略 1. 智谱清言平台演示 CogView-3 核心能力 1.1 CogView3 技术架构…...

操作系统高频(六)linux内核

操作系统高频&#xff08;六&#xff09;linux内核 1.内核态&#xff0c;用户态的区别⭐⭐⭐ 内核态和用户态的区别主要在于权限和安全性。 权限&#xff1a;内核态拥有最高的权限&#xff0c;可以访问和执行所有的系统指令和资源&#xff0c;而用户态的权限相对较低&#x…...

Ubuntu系统安装Cpolar 实现内网穿透教程

文章目录 方法 1&#xff1a;使用官方脚本快速安装&#xff08;推荐&#xff09;方法 2&#xff1a;手动下载安装包配置与使用常见问题 方法 1&#xff1a;使用官方脚本快速安装&#xff08;推荐&#xff09; 下载安装脚本 打开终端&#xff0c;执行以下命令下载并运行安装脚本…...

Trustworthy Machine Learning

1. 可信任机器学习的核心概念 1.1 可信任性的定义 稳健性&#xff08;Robustness&#xff09;&#xff1a; 机器学习模型在面对数据噪声、分布变化或对抗性攻击时仍能维持其预测性能的能力。 公平性&#xff08;Fairness&#xff09;&#xff1a; 避免 AI 决策对某些群体存在…...

Enovia许可管理系统的特点

在当今竞争激烈的市场环境中&#xff0c;企业对于产品生命周期管理&#xff08;PLM&#xff09;的需求日益增加。Enovia许可管理系统&#xff0c;作为一款先进的许可证管理工具&#xff0c;凭借其卓越的特点&#xff0c;助力企业实现资源的高效管理和最大化利用。本文将详细介绍…...

【CSS】样式与效果

个人主页&#xff1a;Guiat 归属专栏&#xff1a;HTML CSS JavaScript 文章目录 1. CSS盒模型1.1 盒模型基础1.2 盒模型类型1.2.1 标准盒模型1.2.2 IE盒模型 2. CSS选择器2.1 基本选择器2.2 组合选择器2.3 伪类和伪元素 3. CSS布局技术3.1 Flexbox布局3.2 Grid布局3.3 定位 4. …...

Python中常用网络编程模块

学习籽料在下方自拿 一、网络基础 网络由下往上分为&#xff1a;物理层、数据链路层、网络怪、传输层、会话层、表示层和应用层。 TCP/IP协议是传输层协议&#xff0c;主要解决数据如何在网络中传输&#xff1b;socket则是对TCP/IP协议的封装&#xff0c;它本身不是协议&…...

python-flask

1.定时任务的时候一定要加--preload&#xff0c;防止 --preload gunicorn --config gunicorn-conf.py --preload index:app 2.source /usr/local/nginx/html/prod/pypd/venv/bin/activate 启动linux的python环境 3.pip freeze > requirements.txt 生成所有依赖 4.p…...

OpenIPC开源FPV之Adaptive-Link信号干扰

OpenIPC开源FPV之Adaptive-Link信号干扰 1. 源由2. 现象3. 分析3.1 冲突弃包3.2 传输丢包 4. 逻辑4.1 可调整参数4.2 可监测参数4.3 逻辑思路 5. 总结6. 参考资料 1. 源由 虽然&#xff0c;OpenIPC作为FPV图传在延时方面使用广播wfb-ng&#xff0c;性能上已经非常棒了。 在权…...

C++ 结构体与函数

一.结构体 1.概念&#xff1a; 结构体&#xff08;struct&#xff09;是一种用户自定义复合数据类型&#xff0c;其中可以包含不同类型的不同成员 2.结构体的应用场景&#xff1a; 我们在使用多个变量描述一个对象时&#xff0c;虽然也可以做到&#xff0c;但是难免显得杂乱…...

【Java全栈】Java + Vue 项目框架与运行流程详解

文章目录 ⭐前言⭐一、框架介绍&#x1f31f;1、后端框架&#xff08;Java Spring Boot&#xff09;&#x1f31f;2、前端框架&#xff08;Vue 3 Element Plus&#xff09; ⭐二、项目结构&#x1f31f;1、后端目录&#xff08;Spring Boot&#xff09;&#x1f31f;2、前端目…...

JAVA:利用 JSONPath 操作JSON数据的技术指南

1、简述 JSONPath 是一种强大的工具&#xff0c;用于查询和操作 JSON 数据。类似于 SQL 的语法&#xff0c;它为处理复杂的 JSON 数据结构提供了简单且高效的解决方案。✨ 代码样例&#xff1a;https://gitee.com/lhdxhl/springboot-example.git 本文将介绍 JSONPath 的基本…...

5.2.1 WPF 通过ItemControl自己做柱状图

1. 最终效果如下图&#xff1a; 1.1 准备数据 ViewModel public class PrimaryItemModel{public double Value { get; set; }public string XLabel { get; set; }}public class MainViewModel{public ObservableCollection<PrimaryItemModel> PrimaryList { get; set; }…...

3.31 代码随想录第三十一天打卡

1049.最后一块石头的重量II (1)题目描述: (2)解题思路: class Solution { public:int lastStoneWeightII(vector<int>& stones) {vector<int> dp(15001, 0);int sum 0;for (int i 0; i < stones.size(); i) sum stones[i];int target sum / 2;for (in…...

基于网启PXE服务器的批量定制系统平台

一.项目背景 公司新购了一批服务器和台式机&#xff0c;需要为台式机和服务器安装系统&#xff0c;一部分需要安装国产OpenEuler&#xff0c;一部分要求安装CentOS 7.9&#xff0c;同时也要满足定制化需求&#xff0c;即按要求分区安装相应软件。 二.项目环境 安装win10/11 …...

Unity光线传播体积(LPV)技术实现详解

一、LPV技术概述 光线传播体积(Light Propagation Volumes)是一种实时全局光照技术&#xff0c;通过将场景中的间接光信息存储在3D网格中&#xff0c;实现动态物体的间接光照效果。 核心优势&#xff1a; 实时性能&#xff1a;相比传统光照贴图&#xff0c;支持动态场景 硬件…...

蓝桥杯备考---》贪心算法之矩阵消除游戏

我们第一次想到的贪心策略一定是找出和最大的行或者列来删除&#xff0c;每次都更新行和列 比如如图这种情况&#xff0c;这种情况就不如直接删除两行的多&#xff0c;所以本贪心策略有误 so我们可以枚举选的行的情况&#xff0c;然后再贪心的选择列和最大的列来做 #include …...

python+playwright 学习-93 结合pands 抓取网页表格数据

playwright 结合 pands 抓取网页表格数据 pandas 直接抓取网页表格数据 web 网页表格数据 """ 上海 202501 天气抓取 """ import pandas as pddf = pd.read_html(fhttp://www.tianqihoubao.com/lishi/shanghai/month/202501.html,encoding...

MVC编程

MVC基本概述 例子——显示本地文件系统结构 先分别拖入ListView,TableView,TreeView 然后在进行布局 在widget.cpp 结果 mock测试 1&#xff0c;先加入json测试对象 2.创建后端目录 3&#xff0c;在src添加新文件 在models文件夹里 在mybucket.h,添加测试用例的三个字段 4.在…...

51单片机总结

写这个文章是用来学习的,记录一下我的学习过程。希望我能一直坚持下去,我只是一个小白,只是想好好学习,我知道这会很难&#xff0c;但我还是想去做&#xff01; 本文写于&#xff1a;2025.03.31 51单片机学习总结&#xff08;有感而发&#xff09; 一、总结结语 一、总结 一路…...

端到端语音识别案例

《DeepSeek大模型高性能核心技术与多模态融合开发&#xff08;人工智能技术丛书&#xff09;》(王晓华)【摘要 书评 试读】- 京东图书 语音识别这一技术正如其名&#xff0c;是通过精密地解析说话人的语音来识别并准确转写出其所说的内容。它不仅仅是一个简单的转录过程&#…...

iOS自定义collection view的page size(width/height)分页效果

前言 想必大家工作中或多或少会遇到下图样式的UI需求吧 像这种cell长度不固定&#xff0c;并且还能实现的分页效果UI还是很常见的 实现 我们这里实现主要采用collection view&#xff0c;实现的方式是自定义一个UICollectionViewFlowLayout的子类&#xff0c;在这个类里对…...

CI/CD基础知识

什么是CI/CD CI&#xff1a;持续集成&#xff0c;开发人员频繁地将代码集成到主干&#xff08;主分支&#xff09;中每次集成都通过自动化构建和测试来验证&#xff0c;从而尽早发现集成错误&#xff0c;常用的CI工具包括Jenkins、Travis CI、CircleCI、GitLab CI等 CD&#…...

MySQL 的 SQL 语句执行顺序

MySQL 的 SQL 语句执行顺序并不完全按照代码的书写顺序执行&#xff0c;而是遵循一套固定的逻辑流程 1. FROM 和 JOIN 作用&#xff1a;确定查询的数据来源&#xff0c;包括表和它们的连接方式&#xff08;如 INNER JOIN, LEFT JOIN 等&#xff09;。 细节&#xff1a; 先执行…...

Dubbo(21)如何配置Dubbo的注册中心?

在分布式系统中&#xff0c;注册中心是一个关键组件&#xff0c;用于服务的注册和发现。Dubbo 支持多种注册中心&#xff0c;包括 ZooKeeper、Nacos、Consul、Etcd 等。下面详细介绍如何配置 Dubbo 的注册中心&#xff0c;以 ZooKeeper 为例。 配置步骤 引入依赖&#xff1a;…...

AISEO中的JSON 如何部署?

一、JSON 是什么&#xff1f; JSON&#xff08;JavaScript Object Notation&#xff09; 是一种轻量级的数据格式&#xff0c;用于在不同系统之间传递结构化信息。它的核心特点是&#xff1a; 易读&#xff1a;用简单的 {键: 值} 对表示数据&#xff0c;例如&#xff1a; json…...

力扣hot100——最长连续序列(哈希unordered_set)

题目链接&#xff1a;最长连续序列 1、错解&#xff1a;数组做哈希表&#xff08;内存超出限制&#xff09; int longestConsecutive(vector<int>& nums) {vector<bool> hash(20000000010, false);for(int i0; i<nums.size();i){hash[1000000000nums[i]]t…...

几种常见的.NET单元测试模拟框架介绍

目录 1. Moq 2. NSubstitute 3. AutoFixture 4. FakeItEasy 总结对比 单元测试模拟框架是一种在软件开发中用于辅助单元测试的工具。 它的主要作用是创建模拟对象来替代真实对象进行测试。在单元测试中&#xff0c;被测试的代码可能依赖于其他组件或服务&#xff0c;如数…...

装饰器模式与模板方法模式实现MyBatis-Plus QueryWrapper 扩展

pom <dependency><groupId>com.github.yulichang</groupId><artifactId>mybatis-plus-join-boot-starter</artifactId> <!-- MyBatis 联表查询 --> </dependency>MPJLambdaWrapperX /*** 拓展 MyBatis Plus Join QueryWrapper 类&…...

11-SpringBoot3入门-整合aop

1、概念&#xff08;个人理解&#xff09; AOP&#xff08;Aspect Oriented Programming&#xff09;&#xff0c;面向切面编程。 1&#xff09;切面&#xff08;Aspect&#xff09;&#xff1a;提供切入连接点的方法 2&#xff09;连接点&#xff08;Joinpoint&#xff09;…...