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

Oracle数据库数据编程SQL<3.5 PL/SQL 存储过程(Procedure)>

存储过程(Stored Procedure)是 Oracle 数据库中一组预编译的 PL/SQL 语句集合,存储在数据库中并可通过名称调用执行。它们是企业级数据库应用开发的核心组件。

目录

一、存储过程基础

1. 存储过程特点

2. 创建基本语法 

3. 存储过程优点

4. 简单示例

二、没有参数的存储过程

1. 简单示例

三、有参数的存储过程

 1. 参数模式

2. 有输入值 IN

3. 有输出值 OUT

4. 有输入输出值IN OUT

(1)编译:

(2)调用​编辑

(3)宏&输入名称​编辑

(4)查看输出结果

四、存储过程的调用总结

五、存储过程中的DML操作

1. 基本DML示例

2. 使用RETURNING子句

六、异常处理

1. 预定义异常

2. 自定义异常

七、游标处理

1. 显式游标

2. REF游标(动态游标)

八、高级特性

1. 自治事务

2. 批量处理(FORALL)

3. 条件编译

九、存储过程管理

1. 查看存储过程

右键查看

2. 重新编译

右键重新编译

右键编辑--执行

3. 权限控制

4. 删除存储过程

十、最佳实践

十一、存储过程和函数的区别


一、存储过程基础

1. 存储过程特点

  • 预编译执行:提高性能,减少解析开销

  • 模块化设计:促进代码重用和维护

  • 增强安全性:通过权限控制保护数据

  • 减少网络流量:客户端只需调用过程名而非发送多句SQL

  • 事务控制:可在过程中管理完整事务

2. 创建基本语法 

CREATE [OR REPLACE] PROCEDURE procedure_name[(parameter1 [IN|OUT|IN OUT] datatype [DEFAULT|:= value],parameter2 [IN|OUT|IN OUT] datatype [DEFAULT|:= value],...)]
[IS|AS][declaration_section]
BEGINexecutable_section
[EXCEPTIONexception_section]
END [procedure_name];
/create {or replace} procedure pro_name(v1 in/out/in out 类型)
as/is
{声明变量}
begin
要执行的语句;
end;
/(1)创建 creat or replace procedure
(2)声明变量
(3)开始 begin
(4)DML操作
(5)异常处理 exception
(6)结束 end

3. 存储过程优点

(1)存储过程只在创建时进行编译,以后每次执行都不需要重新编译,而一般的SQL语句每执行一次就编译一次,所以使用存储过程可以提高数据库的执行速度。

(2)当对数据库进行复杂操作时(比如对多个表进行查询、修改操作),可以将此复杂的事务处理结合一起使用这些操作。如果用SQL需要多次连接数据库,如果用存储过程,只需要连接一次数据库。

(3)存储过程可以重复使用,可以减少数据库开发人员的工作量。

4. 简单示例

CREATE OR REPLACE PROCEDURE update_employee_salary(       --创建--存过主题结构
---------------------------------------------------------------------------------p_emp_id IN employees.employee_id%TYPE,p_percent IN NUMBER DEFAULT 10
) ASv_old_salary employees.salary%TYPE;                   --声明变量--存过主题结构
---------------------------------------------------------------------------------
BEGIN                                                     --开始--存过主题结构
----------------------------------------------------------------------------------- 获取当前薪资SELECT salary INTO v_old_salaryFROM employeesWHERE employee_id = p_emp_id;-- 更新薪资UPDATE employeesSET salary = salary * (1 + p_percent/100)WHERE employee_id = p_emp_id;-- 输出结果DBMS_OUTPUT.PUT_LINE('员工ID ' || p_emp_id || ' 薪资从 ' || v_old_salary || ' 调整为 ' || (v_old_salary * (1 + p_percent/100)));COMMIT;                                               --DML操作--存过主题结构
---------------------------------------------------------------------------------
EXCEPTIONWHEN NO_DATA_FOUND THENDBMS_OUTPUT.PUT_LINE('错误: 未找到员工ID ' || p_emp_id);ROLLBACK;WHEN OTHERS THENDBMS_OUTPUT.PUT_LINE('错误: ' || SQLERRM);ROLLBACK;                                         --异常处理--存过主题结构
---------------------------------------------------------------------------------
END update_employee_salary;                               --结束--存过主题结构
---------------------------------------------------------------------------------
/

二、没有参数的存储过程

1. 简单示例

--编写一个存储过程,将emp表中和编号7788相同部门的员工信息插入到
--emp3中,将工作为CLERK的工资加300后插入到emp4中。
-- 创建
create or replace procedure pro2 as   --创建--存过主题结构
begin                                 --开始--存过主题结构
--------------------------------------------------------------------DML操作insert into emp3select *from empwhere deptno = (select deptno from emp where empno = 7788);--DML操作insert into emp4select e.empno,e.ename,e.job,e.mgr,e.hiredate,e.sal + 300,e.comm,e.deptnofrom emp ewhere job = 'CLERK';
------------------------------------------------------------------
end;                                   --结束--存过主题结构
/
-- 调用:
call pro2();
-- 查询、验证
select * from emp3;
select * from emp4;

三、有参数的存储过程

 1. 参数模式

模式描述示例
IN只读参数(默认)p_id IN NUMBER
OUT只写参数,返回给调用者p_result OUT VARCHAR2
IN OUT可读写参数p_counter IN OUT NUMBER

2. 有输入值 IN

--输入员工编号,输出姓名和薪资。
-- 创建
create or replace procedure pro1(v_empno number) asv_name varchar2(20);v_sal  emp.sal%type;
beginselect ename, sal into v_name, v_sal from emp where empno = v_empno;dbms_output.put_line(v_name || v_sal);
end;
-- 调用:
call pro1(7788);【调用方法】
在sql窗口  call pro_name(参数); --sql窗口括号不能省
在命令窗口 exec pro_name(参数);/*===============================================================================*/
【练习1】
--创建一张emp3数据同emp
--更改emp3的sal列的长度为number(20,2)
--编写一个存储过程
--输入一个数字和一个部门编号
--要求数字是0-9的整数(如果不是,抛出异常,并打印'请输入0-9的整数')
--当部门人数小于该数字,将该部门的员工信息插入到emp1--显示插入了多少行
--当部门人数大于该数字,将该部门的员工姓名,编号删除--并显示删除了多少人
--当部门人数等于该数字,不该部门的全部员工工资变成原工资的二次方--并显示增加了多少人的工资
-- 准备:
CREAT TABLE EMP3 AS SELECT * FORM EMP;
ALTER TABLE EMP3 MODIFY SAL NUMBER(20,2);
-- 创建:
CREATE OR REPLACE PROCEDURE PRO_3(V1 NUMBER,V_DEPTNO NUMBER) AS
ERR EXCEPTION;
V3 NUMBER;
BEGINIF v1 NOT IN (0,1,2,3,4,5,6,7,8,9)THENRAISE ERR;END IF;SELECT COUNT(*) INTO V3 FROM EMP3 WHERE DEPTNO=V_DEPTNO;IF V3<V1 THEN INSERT INTO EMP1 SELECT * FROM EMP3 WHERE DEPTNO=V_DEPTNO;dbms_output.put_line('插入了'||sql%rowcount||'行');ELSIF v3>v1 THEN UPDATE emp3 SET ename=NULL,empno=null WHERE deptno=v_deptno;dbms_output.put_line('删了'||sql%rowcount||'人');ELSE UPDATE emp3 SET sal=POWER(sal,2) WHERE deptno=v_deptno;dbms_output.put_line(sql%rowcount||'人的工资增加了');END IF; 
EXCEPTION WHEN ERR THEN DBMS_output.put_line('请输入0-9的整数');END;
-- 调用:
CALL pro_3(2,10)
-- 验证:
SELECT * FROM emp3/*===============================================================================*/
【练习2】
--新建一张表emp2和emp数据相同。
--编写一个存储过程,输入一个数字和一个部门编号。
--要求数字是0-9的整数
--当该部门人数小于该数字将该部门员工信息插入到emp3中;
--当该部门人数大于该数字将该部门的员工姓名编号删除;
--当该部门人数等于该数字则该部门全部员工工资加666。
-- 创建
create or replace procedure pro4(v_num number, v_deptno number) as exception;
beginselect count(*) into v_count from emp where deptno = v_deptno;if v_num not in (0, 1, 2, 3, 4, 5, 6, 7, 8, 9) thenraise err;elsif v_count < v_num theninsert into emp3select * from emp2 where deptno = v_deptno;dbms_output.put_line(v_deptno||'部门人数' || v_count || '<' || v_num);elsif v_count > v_num thenupdate emp2 set ename = null, empno = null where deptno = v_deptno;dbms_output.put_line(v_deptno||'部门人数' || v_count || '>' || v_num);elseupdate emp2 set sal = sal + 666 where deptno = v_deptno;dbms_output.put_line(v_deptno||'部门人数' || v_count || '=' || v_num);end if;
exceptionwhen err thendbms_output.put_line('请输入0-9的整数');raise;
end;
-- 调用:
call pro4(3,10);

3. 有输出值 OUT

/*===============================================================================*/
【练习1】
--输入:姓名
--输出:如果工资比MILLER高,输出高,比MILLER低输出低,一样的话巧了
-- 创建
create or replace procedure pro3(v1 varchar2, v2 out varchar2) asv_3 number;v_4 number;
beginselect sal into v_sal_m from emp where ename = 'MILLER';select sal into v_sal_t from emp where ename = v1;if v_sal_t > v_sal_m thenv2:='高';elsif v_sal_t < v_sal_m thenv2:='低';else v2:='巧了';end if;
end;
/
-- 调用:
declarev2 varchar2(4);
beginpro3(&a, v2);dbms_output.put_line(v2);
end;
/
/*===============================================================================*/
【练习2】
--输入:姓名
--输出: 如果部门和MILLER一样,输出一样,不一样输出不一样
-- 创建
create or replace procedure pro4(v1 varchar2, v2 out varchar2) asv_deptno_m number;v_deptno   number;
beginselect deptno into v_deptno_m from emp where ename = 'MILLER';select deptno into v_deptno from emp where ename = v1;if v_deptno = v_deptno_m thenv2 := '一样';elsev2 := '不一样';end if;dbms_output.put_line(v2);
end;
/
-- 调用:
declarev2 varchar2(6);
beginpro4('&a', v2);
end;
/
/*===============================================================================*/
【练习3】存过名称不建议使用中文
--输入:姓名
--输出:如果部门和MILLER一样,输出一样,不一样输出不一样
-- 创建
create or replace procedure 判断是否和MILLER信息一样(v1 varchar2, v2 out varchar2) asv_d_m number;v_d_t number;
beginselect deptno into v_d_m from emp where ename = 'MILLER';select deptno into v_d_t from emp where ename = v1;if v_d_t = v_d_m thenv2 := '一样';elsev2 := 'MMP不一样,滚';end if;
end;
/
-- 调用:
declarev2 varchar2(20);
begin判断是否和MILLER信息一样(&a, v2);dbms_output.put_line(v2);
end;
/

4. 有输入输出值IN OUT

--输入两个名字,把两个人的名字的首字母大写并拼接
--输出更新后的名字
-- 创建
CREATE OR REPLACE PROCEDURE pro_5(v1 IN OUT VARCHAR2,v2 IN OUT VARCHAR2) AS
BEGIN v1:=INITCAP(v1);v2:=INITCAP(v2);
END;
-- 调用
DECLAREv1 VARCHAR2(20):='&A';v2 VARCHAR2(20):='&B';
BEGINpro_5(v1,v2);dbms_output.put_line(v1||v2);
END;

(1)编译:

(2)调用

(3)宏&输入名称

(4)查看输出结果

四、存储过程的调用总结

存过不同类型创建调用方式

没有参数

call pro_name()/exec pro_name

只有输入值

call pro_name(参数)/exec pro_name(参数)

有输出值

pl/sql调用

有输入输出

pl/sql调用

五、存储过程中的DML操作

1. 基本DML示例

CREATE OR REPLACE PROCEDURE transfer_employee(p_emp_id IN NUMBER,p_new_dept_id IN NUMBER,p_salary_adjustment IN NUMBER DEFAULT 0
) ASv_old_dept_id NUMBER;v_new_dept_name VARCHAR2(100);
BEGIN-- 获取原部门IDSELECT department_id INTO v_old_dept_idFROM employeesWHERE employee_id = p_emp_id;-- 获取新部门名称SELECT department_name INTO v_new_dept_nameFROM departmentsWHERE department_id = p_new_dept_id;-- 更新员工记录UPDATE employeesSET department_id = p_new_dept_id,salary = salary + p_salary_adjustmentWHERE employee_id = p_emp_id;-- 记录调动历史INSERT INTO transfer_history (transfer_id, employee_id, from_dept_id, to_dept_id, transfer_date) VALUES (transfer_seq.NEXTVAL, p_emp_id,v_old_dept_id, p_new_dept_id,SYSDATE);COMMIT;DBMS_OUTPUT.PUT_LINE('成功将员工 ' || p_emp_id || ' 从部门 ' || v_old_dept_id || ' 调至 ' || v_new_dept_name);
EXCEPTIONWHEN OTHERS THENDBMS_OUTPUT.PUT_LINE('调动失败: ' || SQLERRM);ROLLBACK;
END transfer_employee;
/

2. 使用RETURNING子句

CREATE OR REPLACE PROCEDURE promote_employee(p_emp_id IN NUMBER,p_new_job_id IN VARCHAR2,p_salary_increase IN NUMBER,p_new_salary OUT NUMBER
) AS
BEGINUPDATE employeesSET job_id = p_new_job_id,salary = salary + p_salary_increaseWHERE employee_id = p_emp_idRETURNING salary INTO p_new_salary;COMMIT;
END promote_employee;
/

六、异常处理

1. 预定义异常

异常触发条件
NO_DATA_FOUNDSELECT INTO未返回行
TOO_MANY_ROWSSELECT INTO返回多行
DUP_VAL_ON_INDEX违反唯一约束
INVALID_CURSOR非法游标操作
ZERO_DIVIDE除零错误
LOGIN_DENIED无效的用户名/密码
PROGRAM_ERRORPL/SQL内部错误

2. 自定义异常

CREATE OR REPLACE PROCEDURE process_order(p_order_id IN NUMBER,p_discount IN NUMBER DEFAULT 0
) ASe_invalid_discount EXCEPTION;PRAGMA EXCEPTION_INIT(e_invalid_discount, -20001);v_order_total NUMBER;
BEGIN-- 验证折扣率IF p_discount < 0 OR p_discount > 0.5 THENRAISE e_invalid_discount;END IF;-- 计算订单总额SELECT SUM(unit_price * quantity) * (1 - p_discount)INTO v_order_totalFROM order_itemsWHERE order_id = p_order_id;-- 更新订单总额UPDATE ordersSET order_total = v_order_totalWHERE order_id = p_order_id;COMMIT;
EXCEPTIONWHEN e_invalid_discount THENDBMS_OUTPUT.PUT_LINE('错误: 折扣率必须在0到0.5之间');ROLLBACK;WHEN NO_DATA_FOUND THENDBMS_OUTPUT.PUT_LINE('错误: 未找到订单 ' || p_order_id);ROLLBACK;WHEN OTHERS THENDBMS_OUTPUT.PUT_LINE('错误代码: ' || SQLCODE);DBMS_OUTPUT.PUT_LINE('错误信息: ' || SQLERRM);ROLLBACK;
END process_order;
/

七、游标处理

1. 显式游标

CREATE OR REPLACE PROCEDURE generate_department_report(p_dept_id IN NUMBER DEFAULT NULL
) ASCURSOR dept_cur ISSELECT department_id, department_nameFROM departmentsWHERE department_id = NVL(p_dept_id, department_id);CURSOR emp_cur(p_dept NUMBER) ISSELECT employee_id, last_name, salaryFROM employeesWHERE department_id = p_deptORDER BY salary DESC;v_total_salary NUMBER;
BEGINFOR dept_rec IN dept_cur LOOPDBMS_OUTPUT.PUT_LINE('部门: ' || dept_rec.department_name);DBMS_OUTPUT.PUT_LINE('--------------------------------');v_total_salary := 0;FOR emp_rec IN emp_cur(dept_rec.department_id) LOOPDBMS_OUTPUT.PUT_LINE(RPAD(emp_rec.employee_id, 10) ||RPAD(emp_rec.last_name, 20) ||TO_CHAR(emp_rec.salary, '$999,999.00'));v_total_salary := v_total_salary + emp_rec.salary;END LOOP;DBMS_OUTPUT.PUT_LINE('--------------------------------');DBMS_OUTPUT.PUT_LINE('部门总薪资: ' || TO_CHAR(v_total_salary, '$999,999.00'));DBMS_OUTPUT.PUT_LINE(CHR(10));  -- 空行END LOOP;
END generate_department_report;
/

2. REF游标(动态游标)

CREATE OR REPLACE PROCEDURE get_employee_data(p_query_type IN VARCHAR2,p_result_set OUT SYS_REFCURSOR
) AS
BEGINIF p_query_type = 'HIGH_SALARY' THENOPEN p_result_set FORSELECT employee_id, last_name, salaryFROM employeesWHERE salary > 10000ORDER BY salary DESC;ELSIF p_query_type = 'BY_DEPARTMENT' THENOPEN p_result_set FORSELECT e.employee_id, e.last_name, d.department_nameFROM employees eJOIN departments d ON e.department_id = d.department_idORDER BY d.department_name, e.last_name;ELSEOPEN p_result_set FORSELECT employee_id, last_name, hire_dateFROM employeesORDER BY hire_date DESC;END IF;
END get_employee_data;
/

八、高级特性

1. 自治事务

允许在过程中创建独立的事务:

CREATE OR REPLACE PROCEDURE log_activity(p_action IN VARCHAR2,p_user IN VARCHAR2 DEFAULT USER
) ASPRAGMA AUTONOMOUS_TRANSACTION;
BEGININSERT INTO activity_log (log_id, action_name, user_name, log_time) VALUES (log_seq.NEXTVAL, p_action,p_user, SYSTIMESTAMP);COMMIT;
EXCEPTIONWHEN OTHERS THENROLLBACK;RAISE;
END log_activity;
/

2. 批量处理(FORALL)

CREATE OR REPLACE PROCEDURE update_multiple_salaries(p_emp_ids IN SYS.ODCINUMBERLIST,p_percent IN NUMBER
) AS
BEGINFORALL i IN 1..p_emp_ids.COUNTUPDATE employeesSET salary = salary * (1 + p_percent/100)WHERE employee_id = p_emp_ids(i);log_activity('批量更新薪资', USER);COMMIT;DBMS_OUTPUT.PUT_LINE('成功更新 ' || SQL%ROWCOUNT || ' 条记录');
EXCEPTIONWHEN OTHERS THENDBMS_OUTPUT.PUT_LINE('批量更新失败: ' || SQLERRM);ROLLBACK;
END update_multiple_salaries;
/

3. 条件编译

CREATE OR REPLACE PROCEDURE debug_procedure ASv_debug BOOLEAN := TRUE;
BEGIN$IF $$DEBUG $THENDBMS_OUTPUT.PUT_LINE('调试信息: 开始执行过程');$END-- 主要处理逻辑$IF $$DEBUG $THENDBMS_OUTPUT.PUT_LINE('调试信息: 过程执行完成');$END
END debug_procedure;
/-- 编译时设置条件
ALTER PROCEDURE debug_procedure COMPILE PLSQL_CCFLAGS = 'debug:true';

九、存储过程管理

1. 查看存储过程

-- 查看源代码
SELECT text FROM user_source 
WHERE name = 'UPDATE_EMPLOYEE_SALARY' 
AND type = 'PROCEDURE'
ORDER BY line;-- 查看依赖关系
SELECT * FROM user_dependencies
WHERE name = 'UPDATE_EMPLOYEE_SALARY';-- 查看参数信息
SELECT argument_name, data_type, in_out
FROM user_arguments
WHERE object_name = 'UPDATE_EMPLOYEE_SALARY';

右键查看

2. 重新编译

ALTER PROCEDURE procedure_name COMPILE;

右键重新编译

右键编辑--执行

3. 权限控制

-- 授予执行权限
GRANT EXECUTE ON procedure_name TO user_name;-- 创建公有同义词
CREATE PUBLIC SYNONYM proc_synonym FOR schema.procedure_name;

4. 删除存储过程

DROP PROCEDURE procedure_name;

十、最佳实践

  1. 命名规范:使用动词+名词形式,如calculate_taxgenerate_report

  2. 参数设计:限制参数数量(通常不超过10个),使用默认参数

  3. 错误处理:捕获预期异常,记录错误日志

  4. 事务管理:保持事务简短,避免长时间锁定

  5. 性能优化:使用批量操作(FORALL, BULK COLLECT)

  6. 文档注释:为过程添加清晰注释

  7. 模块化:将复杂逻辑分解为多个小过程

  8. 避免硬编码:使用参数和常量代替字面值

十一、存储过程和函数的区别

  • 1.调用方式不一样。
  • 2.DML操作一般不用函数。
  • 3.函数有return返回值,存储过程没有。
  • 4.如果返回值超过一个,一般用存储过程。
  • 5.存储过程可以调用函数,函数不能调用存储过程。
  • 6.存储过程用来实现某些操作或者业务,函数用来实现某种功能。
存储过程函数
用于在数据库中完成特定的操作或者任务(如插入、删除等)用于特定的数据(如选择)
程序头部声明用procedure程序头部声明用function
程序头部声明不需描述返回类型程序头部声明时要描述返回类型,而且PL/SQL块中至少要包括一个有效的return语句
可以使用in/out/in out三种模式的参数可以使用in/out/in out三种模式的参数
可作为一个独立的PL/SQL语句来执行不能独立执行,必须作为表达式的一部分调用
可以通过out/in out返回零个或多个值通过return语句返回一个值,且改值要与声明部分一致,也可以是通过out类型的参数带出的变量
SQL语句(DML或SELECT)中不可调用存储过程SQL语句(DML或SELECT)中可以调用函数

存储过程是Oracle数据库编程的核心组件,合理设计和使用的存储过程可以显著提高应用性能、安全性和可维护性。通过掌握上述技术,您可以构建高效、可靠的企业级数据库应用。

相关文章:

Oracle数据库数据编程SQL<3.5 PL/SQL 存储过程(Procedure)>

存储过程(Stored Procedure)是 Oracle 数据库中一组预编译的 PL/SQL 语句集合&#xff0c;存储在数据库中并可通过名称调用执行。它们是企业级数据库应用开发的核心组件。 目录 一、存储过程基础 1. 存储过程特点 2. 创建基本语法 3. 存储过程优点 4. 简单示例 二、没有…...

六级词汇量积累day13

commend 表扬 exhaust 耗尽&#xff0c;用尽 weary 疲惫的&#xff0c;劳累的 fatigue 疲惫&#xff0c;劳累 obese 臃肿的&#xff0c;肥胖的 adopt 采纳&#xff0c;收养 adapt 适应 accomplish 完成&#xff0c;实现 accomplishment 成就 achieve 实现&#xff0c;完成 achi…...

蓝桥杯15届JAVA_A组

将所有1x1转化为2x2 即1x1的方块➗4 然后计算平方数 记得-1 2 import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.PrintWriter;public class Main{static BufferedReader in new BufferedReader(new In…...

OpenCV图像输入输出模块imgcodecs(imwrite函数的用法)

《OpenCV计算机视觉开发实践&#xff1a;基于Python&#xff08;人工智能技术丛书&#xff09;》(朱文伟&#xff0c;李建英)【摘要 书评 试读】- 京东图书 3.2.3 imwrite保存图片 函数imwrite可以用来输出图像到文件&#xff0c;其声明如下&#xff1a; imwrite(filename,…...

win 远程 ubuntu 服务器 安装图形界面

远程结果&#xff1a;无法使用docker环境使用此方法 注意要写IP和:数字 在 ubuntu 服务器上安装如下&#xff1a; # 安装 sudo apt-get install tightvncserver # 卸载 sudo apt purge tightvncserver sudo apt autoremove#安装缺失的字体包&#xff1a; sudo apt update s…...

地下管线三维建模软件工具MagicPipe3D V3.6.1

经纬管网建模系统MagicPipe3D&#xff0c;基于二维矢量管线管点数据本地离线参数化构建地下管网三维模型&#xff08;包括管道、接头、附属设施等&#xff09;&#xff0c;输出标准3DTiles、Obj模型等格式&#xff0c;支持Cesium、Unreal、Unity、Osg等引擎加载进行三维可视化、…...

vue子组件生命周期的执行顺序

在 Vue 中&#xff0c;子组件的生命周期钩子函数的执行顺序受父组件的影响&#xff0c;通常遵循**“先创建子组件&#xff0c;后创建父组件&#xff1b;先销毁父组件&#xff0c;后销毁子组件”**的原则。 1. 组件创建&#xff08;挂载&#xff09;阶段 当父组件挂载时&#x…...

【含文档+PPT+源码】基于微信小程序的在线考试与选课教学辅助系统

项目介绍 本课程演示的是一款基于微信小程序的在线考试与选课教学辅助系统&#xff0c;主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的 Java 学习者。 1.包含&#xff1a;项目源码、项目文档、数据库脚本、软件工具等所有资料 2.带你从零开始部署运行本套系统…...

树莓派超全系列文档--(17)树莓派配置显示器

树莓派配置显示器 显示支持 HDMI 显示器设置分辨率和旋转手动设置分辨率和旋转确定显示设备名称设置自定义分辨率设置自定义旋转 控制台分辨率和旋转 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 显示 要配置 Raspberry Pi 使用非默认显示模式…...

python将pdf文件转为图片,如果pdf文件包含多页,将转化的多个图片通过垂直或者水平合并成一张图片

要将PDF文件转换为图片&#xff0c;并将多页PDF垂直合并成一张图片&#xff0c;可以使用PyMuPDF&#xff08;也称为fitz&#xff09;库来读取PDF文件&#xff0c;并使用Pillow库来处理和合并图片。以下是一个示例代码&#xff0c;展示了如何实现这个功能&#xff1a; 首先&…...

JVM基础原理

JVM是一个虚拟化的计算机&#xff0c;它可以执行Java字节码文件&#xff08;.class文件&#xff09;&#xff0c;实现Java程序跨平台的特性。JVM负责将Java程序的字节码翻译成具体操作系统的机器码&#xff0c;从而能够在不同的平台上运行。JVM的核心原理涉及以下几个重要方面 …...

Miniforge3高效管理 Python环境:2025年最新实践指南

Miniforge3 高效管理 Python 环境:2025 年最新实践指南 在现代开发中,灵活高效地管理 Python 环境至关重要。Miniforge3 作为一款轻量级 Conda 管理工具,不仅默认采用更新更快的 conda-forge 软件源,还对 ARM 架构(例如 Apple M1/M2/M3)有着出色的适配性。相比于传统的 …...

31天Python入门——第17天:初识面向对象

你好&#xff0c;我是安然无虞。 文章目录 面向对象编程1. 什么是面向对象2. 类(class)3. 类的实例关于self 4. 对象的初始化5. __str__6. 类之间的关系继承关系组合关系 7. 补充练习 面向对象编程 1. 什么是面向对象 面向对象编程是一种编程思想,它将现实世界的概念和关系映…...

困于环中的机器人

************* c topic: 1041. 困于环中的机器人 - 力扣&#xff08;LeetCode&#xff09; ************* Inspect the topic first. And it looks really familiar with another robot topic. 657. 机器人能否返回原点 - 力扣&#xff08;LeetCode&#xff09;https://lee…...

阿里 FunASR 开源中文语音识别大模型应用示例(准确率比faster-whisper高)

文章目录 Github官网简介模型安装非流式应用示例流式应用示例 Github https://github.com/modelscope/FunASR 官网 https://www.funasr.com/#/ 简介 FunASR是一个基础语音识别工具包&#xff0c;提供多种功能&#xff0c;包括语音识别&#xff08;ASR&#xff09;、语音端…...

spring boot前后端开发上传文件时报413(Request Entity Too Large)错误的可能原因及解决方案

可能原因及解决方案 1. Spring Boot默认文件大小限制 原因&#xff1a;Spring Boot默认单文件最大为1MB&#xff0c;总请求体限制为10MB。解决方案&#xff1a; 在application.properties中配置&#xff1a;spring.servlet.multipart.max-file-size10MB # 单文件最大 spring…...

Transformer:破局山地暴雨预测的「地形诅咒」--AI智能体开发与大语言模型的本地化部署、优化技术

极端降雨预测的技术痛点与边缘破局 1. 传统预警系统的三重瓶颈‌ ‌延迟致命‌&#xff1a;WRF模式在1km分辨率下3小时预报耗时>45分钟&#xff0c;错过山洪黄金响应期 ‌地形干扰大‌&#xff1a;复杂地形区&#xff08;如横断山脉&#xff09;降水预测误差超50% ‌数据…...

游戏引擎学习第187天

看起来观众解决了上次的bug 昨天遇到了一个相对困难的bug&#xff0c;可以说它相当棘手。刚开始的时候&#xff0c;没有立刻想到什么合适的解决办法&#xff0c;所以今天得从头开始&#xff0c;逐步验证之前的假设&#xff0c;收集足够的信息&#xff0c;逐一排查可能的原因&a…...

05-02-自考数据结构(20331)- 动态查找-知识点

自考数据结构动态查找算法主要讲二叉树和平衡二叉树,但是感觉到了,就又续接了一部分,所以这篇备考的小伙伴着重看前两种就可以了。 知识拓扑 知识点介绍 二叉排序树(BST) 定义 二叉排序树(Binary Search Tree)又称二叉查找树,它或者是一棵空树,或者是具有下列性质的二…...

PyQt6实例_批量下载pdf工具_使用pyinstaller与installForge打包成exe文件

目录 前置&#xff1a; 步骤&#xff1a; step one 准备好已开发完毕的项目代码 step two 安装pyinstaller step three 执行pyinstaller pdfdownload.py&#xff0c;获取初始.spec文件 step four 修改.spec文件&#xff0c;将data文件夹加入到打包程序中 step five 增加…...

NVR接入录像回放平台EasyCVR视频融合平台城市/乡镇污水处理厂解决方案

一、方案背景 随着经济的快速发展和城市化的加快&#xff0c;城市污水排放量急剧增加&#xff0c;给城市环境和粮食安全带来了威胁。因此&#xff0c;污水处理厂的建设和高效运营成为对城市环境保护的重要任务。 目前&#xff0c;国内许多城市虽已建成污水处理系统&#xff0…...

Vue2 vs Vue3 生命周期全面对比:created 的进化与革新!!!

&#x1f3af; Vue2 vs Vue3 生命周期全面对比&#xff1a;created 的进化与革新 &#x1f525; 核心差异全景图 一、钩子函数命名与定位变化 1. 命名规范革新 Vue2 钩子Vue3 钩子 (Options API)Vue3 Composition APIbeforeCreate❌ 无setup() 替代created✅ 保留setup() 替代…...

Ubuntu 22.04安装MongoDB:GLM4模型对话数据收集与微调教程

在Ubuntu 22.04安装MongoDB Community Edition的教程请点击下方链接进行参考&#xff1a; 点击这里获取MongoDB Community Edition安装教程 今天将为大家带来如何微调GLM4模型并连接数据库进行对话的教程。快跟着小编一起试试吧~ 1. 大模型 ChatGLM4 微调步骤 1.1 从 github…...

并查集(Union-Find Set)课程笔记

目录 1. 并查集原理 2. 并查集的实现 3. 并查集应用 应用 1&#xff1a;省份数量问题 应用 2&#xff1a;等式方程的可满足性 1. 并查集原理 并查集用于处理需要将不同元素划分成若干不相交集合的问题。最开始时&#xff0c;每个元素都是单独的一个集合&#xff0c;随后根…...

算法刷题记录——LeetCode篇(1.4) [第31~40题](持续更新)

更新时间&#xff1a;2025-03-29 算法题解目录汇总&#xff1a;算法刷题记录——题解目录汇总技术博客总目录&#xff1a;计算机技术系列博客——目录页 优先整理热门100及面试150&#xff0c;不定期持续更新&#xff0c;欢迎关注&#xff01; 32. 最长有效括号 给你一个只包…...

【区块链安全 | 第十四篇】类型之值类型(一)

文章目录 值类型布尔值整数运算符取模运算指数运算 定点数地址&#xff08;Address&#xff09;类型转换地址成员balance 和 transfersendcall&#xff0c;delegatecall 和 staticcallcode 和 codehash 合约类型&#xff08;Contract Types&#xff09;固定大小字节数组&#x…...

一款超级好用且开源免费的数据可视化工具——Superset

认识Superset 数字经济、数字化转型、大数据等等依旧是如今火热的领域&#xff0c;数据工作有一个重要的环节就是数据可视化。 看得见的数据才更有价值&#xff01; 现如今依旧有多数企业号称有多少多少数据&#xff0c;然而如果这些数据只是呆在冷冰冰的数据库或文件内则毫无…...

android gradle一直编译不下来,可能是打开了gradle离线模式

gradle离线模式 当然&#xff0c;如果本地已经将gradle&#xff0c;lib都下载下来了&#xff0c;也可以打开这个离线模式&#xff0c;不然重启AS的时候可能会重新走一次下载流程...

(C语言)学生信息表(学生管理系统)(基于通讯录改版)(正式版)(C语言项目)

1.首先是头文件&#xff1a; //student.h //头文件//防止头文件被重复包含#pragma once//宏定义符号常量&#xff0c;方便维护和修改 #define ID_MAX 20 #define NAME_MAX 20 #define AGE_MAX 5 #define SEX_MAX 5 #define CLA_MAX 20 //定义初始最大容量 #define MAX 1//定义结…...

【Linux】Linux 系统启动流程详解

1. BIOS/UEFI 阶段 硬件自检&#xff08;POST&#xff09; BIOS/UEFI 执行硬件检查&#xff08;内存、CPU、外设等&#xff09;。若硬件异常&#xff0c;通过蜂鸣码或屏幕提示错误。 选择启动设备 按配置顺序&#xff08;硬盘、U盘、网络等&#xff09;寻找可引导设备。BIOS&a…...

Jetson 设备卸载 OpenCV 4.5.4 并编译安装 OpenCV 4.2.0

‌一、卸载 OpenCV 4.5.4‌ 清除已安装的 OpenCV 库‌ sudo apt-get purge libopencv* python3-opencv # 卸载所有APT安装的OpenCV包‌:ml-citation{ref"1,3" data"citationList"}sudo apt autoremove # 清理残留依赖‌:ml-citation{ref"1,4"…...

【计算机网络】OSI七层模型完全指南:从比特流到应用交互的逐层拆解

OSI模型 导读一、概念二、模型层次结构2.1 物理层&#xff08;Physical Layer&#xff09;2.2 数据链路层&#xff08;Data Link Layer&#xff09;​2.3 ​网络层&#xff08;Network Layer&#xff09;​2.4 ​传输层&#xff08;Transport Layer&#xff09;​2.5 ​会话层&…...

渗透测试:登录页面的测试-弱口令思路和实战

渗透测试&#xff1a;登录页面的测试思路和实战 渗透测试&#xff08;Penetration Testing&#xff09;&#xff0c;也称为“渗透性测试”&#xff0c;是一种评估计算机系统、网络或Web应用安全性的一种方法。它通过模拟真实世界中的攻击手段和策略&#xff0c;来检测目标系统…...

Android BottomNavigationView 完全自定义指南:图标、文字颜色与选中状态

1. 核心功能概述 通过 Material Design 的 BottomNavigationView&#xff0c;你可以轻松实现以下自定义&#xff1a; ✅ 动态切换选中/默认图标 ✅ 自定义选中与默认文字颜色 ✅ 控制文字显示模式&#xff08;始终显示/仅选中显示/自动隐藏&#xff09; ✅ 添加动画和高级样…...

提示词工程

参考网站&#xff1a;提示工程指南 – Nextra 声明&#xff1a;我现在也才刚刚开始学习 人工智能&#xff0c;我会着重于 agent 的学习&#xff0c;如果有不对的地方请大家及时指出。 模型设置 前言 在向大模型发送请求时&#xff0c;常常能看到以下参数&#xff1a; {&qu…...

分页查询原理与优化方案完全指南

分页查询原理与优化方案完全指南 一、分页查询基础原理 1.1 传统分页实现方式 分页查询的核心目的是将大数据集分割成多个小块进行展示,最常见的实现方式是使用LIMIT-OFFSET语法: -- 基础分页查询 SELECT * FROM table_name ORDER BY id LIMIT page_size OFFSET (page_n…...

嵌入式软件设计规范框架(MISRA-C 2012增强版)

以下是一份基于MISRA-C的嵌入式软件设计规范&#xff08;完整技术文档框架&#xff09;&#xff0c;包含编码规范、安全设计原则和工程实践要求&#xff1a; 嵌入式软件设计规范&#xff08;MISRA-C 2012增强版&#xff09; 一、编码基础规范 1.1 文件组织 头文件保护 /* 示…...

课程6. 决策树

课程6. 决策树 决策树直觉模型结构几何解释决策树的构建ID3算法信息内容标准使用决策树处理差距推广到回归问题分支标准与经典损失函数的关系 过度拟合和欠拟合欠拟合过拟合 优点和缺点案例随机生成数据集分类IRIS 数据集解决回归问题的一个简短例子 决策树 今天我们继续探索一…...

【UE5.3.2】初学1:适合初学者的入门路线图和建议

3D人物的动作制作 大神分析:3D人物的动作制作通常可以分为以下几个步骤: 角色绑定(Rigging):将3D人物模型绑定到一个骨骼结构上,使得模型能够进行动画控制。 动画制作(Animation):通过控制骨骼结构,制作出人物的各种动作,例如走路、跳跃、打斗等。 动画编辑(Ani…...

OpenCV 图形API(4)内核 API

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 G-API 背后的核心理念是可移植性——使用 G-API 构建的流水线必须是可移植的&#xff08;或者至少具备可移植的能力&#xff09;。这意味着&…...

pom.xml与.yml,java配置参数传递

pom.xml与 .yml java配置参数传递 在Java项目中&#xff0c;通过 pom.xml 和 .yml 文件&#xff08;如 application.yml&#xff09;传递变量通常涉及 构建时&#xff08;Maven&#xff09;和 运行时&#xff08;Spring Boot&#xff09;两个阶段的配置。以下是具体的实现方法&…...

LeetCode算法题(Go语言实现)_21

题目 给你一个整数数组 arr&#xff0c;如果每个数的出现次数都是独一无二的&#xff0c;就返回 true&#xff1b;否则返回 false。 一、代码实现 func uniqueOccurrences(arr []int) bool {freq : make(map[int]int)// 统计每个数字的出现次数for _, num : range arr {freq[n…...

Docker部署前后端分离项目

镜像下载 在有网络的电脑下载镜像&#xff08;Windows&#xff09;&#xff1a;依次在CMD命令台执行以下代码 docker pull node:20docker pull openjdk:22-jdkdocker pull mysql:8.0docker pull nginx:1.27 删除镜像代码&#xff1a; docker rmi node:latest 查看镜像列表…...

Linux系统安装MySQL 8.0完整指南(新手友好版)

MySQL作为最流行的开源关系型数据库之一&#xff0c;广泛应用于各种开发和生产环境。本教程将详细介绍在Linux系统上安装MySQL 8.0的全过程&#xff0c;包括卸载旧版本、安装新版本、基础配置和远程连接设置&#xff0c;特别适合Linux新手学习使用。 一、卸载旧版MySQL&#x…...

第二次作业

#创建表&#xff0c;把id设为主键 mysql> create table test02(-> id int primary key, #----主键约束-> name varchar(50)-> ); Query OK, 0 rows affected (0.02 sec) ​ #插入数据测试 mysql> insert into test02 values(1,"成都"); Query OK, 1 r…...

AI大模型下传统 Spring Java工程开发的演进和变化方向

1. 背景和动因 传统Spring开发优势&#xff1a;Spring生态以稳定、模块化、依赖注入&#xff08;DI&#xff09;等特性著称&#xff0c;长期支撑企业级应用开发&#xff0c;具备高扩展性和可维护性。AI大模型崛起&#xff1a;近几年&#xff0c;LLM&#xff08;如GPT-4、LLaMA…...

周学习总结

这周继续学习了Java的知识点&#xff0c;还写了考查递归、递推与贪心的算法题。 算法小结 递归与递推一般是观察观察题干&#xff0c;分析题目的规律&#xff0c;可能还会用到分治算法&#xff0c;推导出一个合理的表达式&#xff0c;再使用函数递归来进行求解。 贪心在求解时…...

‌19.思科路由器:OSPF协议引入直连路由的实验研究

思科路由器:OSPF协议引入直连路由的实验研究 一、实验拓扑二、基本配置2.1、sw1的配置2.2、开启交换机三层功能三、ospf的配置3.1、R1的配置3.2、R2的配置3.3、重启ospf进程四、引入直连路由五、验证结果随着互联网技术的不断发展,路由器作为网络互联的关键设备,其性能与稳定…...

Zcanpro搭配USBCANFD-200U在新能源汽车研发测试中的应用指南(周立功/致远电子)

——国产工具链的崛起与智能汽车测试新范式 引言&#xff1a;新能源汽车测试的国产化突围 随着新能源汽车智能化、网联化程度的提升&#xff0c;研发测试面临三大核心挑战&#xff1a;多协议融合&#xff08;CAN FD/LIN/以太网&#xff09;、高实时性数据交互需求、复杂工况下…...

JSON的基础知识

文章目录 前言json协议的基本格式json 数组类型 的语法规则json协议报文的实例json常见的一些格式错误在gd32中使用cjson库小结 前言 json协议在互联网应用&#xff0c;物联网应用中都会用到。所谓工欲善其事必先利其器&#xff0c;我们需要学习了解json协议的具体格式&#xf…...