Oracle数据库数据编程SQL<3.4 PL/SQL 自定义函数>
自定义函数是Oracle数据库中可重用的PL/SQL代码块,它接受参数、执行操作并返回一个值。函数可以在SQL语句中直接调用,极大增强了SQL的处理能力。
| 分类 | 调用 | ||
| 没有参数 | 没有输入输出 | 写SQL不加参数 | |
| 有参数 | 有输入无输出 | 写SQL加参数 | |
| 无输入有输出 | 输出变量 | 写PL/SQL匿名块或者自定义函数、存储过程调用 | |
| 输出动态游标 | |||
| 有输入有输出 | 写PL/SQL匿名块或者自定义函数、存储过程调用 | ||
目录
一、函数基本结构
1. 创建语法:必须有返回值
2. 基本示例
二、函数参数模式
三、无参数:没有输入输出
四、有参数:只输入IN--用select调用
五、有参数:有输出OUT--plsql调用
1、输出变量
2、输出游标
六、有参数:有输入输出值IN OUT--必须用宏代换&
七、函数返回值
1. 返回标量值
2. 返回复合类型
(1)使用%ROWTYPE
(2)使用自定义类型
八、函数中的DML操作
示例:审计函数
九、确定性函数与并行处理
1. 确定性函数(DETERMINISTIC)
2. 并行处理(PARALLEL_ENABLE)
十、管道表函数(PIPELINED)
1. 基本管道函数
2. 带参数的管道函数
十一、函数的调用方式
1. 在PL/SQL中调用
2. 在SQL语句中调用
3. 在DML语句中调用
十二、函数的管理与维护
1. 查看函数定义
2. 重新编译函数
3. 删除函数
4. 函数权限控制
十三、函数设计最佳实践
1. 单一职责原则:
2. 合理命名:
3. 参数设计:
4. 错误处理:
5. 性能考虑:
6. 文档注释:
十四、高级函数特性(了解)
1. 函数重载(在包中)
2. 递归函数
3. 使用上下文函数(12c+)
一、函数基本结构
1. 创建语法:必须有返回值
【语法】关键词【function,return】
CREATE [OR REPLACE] FUNCTION function_name[(parameter1 [IN|OUT|IN OUT] datatype [DEFAULT|:= value],parameter2 [IN|OUT|IN OUT] datatype [DEFAULT|:= value],...)]
RETURN return_datatype
[IS|AS][declaration_section]
BEGINexecutable_section[RETURN value;]
[EXCEPTIONexception_section]
END [function_name];create {or replace} function fun_name
(v1 in|out|in out 数据类型{无长度}/*可以加多各参数*/)
return 类型{无长度}
as|is {声明变量/声明游标}---如果没有变量{类型长度}声明,也可以不用声明
begin要执行的语句;[return 值|游标;][exception][return 值|游标;]
end;
/
2. 基本示例
CREATE OR REPLACE FUNCTION get_employee_name(p_emp_id IN employees.employee_id%TYPE
) RETURN VARCHAR2
ISv_full_name VARCHAR2(100);
BEGINSELECT first_name || ' ' || last_name INTO v_full_nameFROM employeesWHERE employee_id = p_emp_id;RETURN v_full_name;
EXCEPTIONWHEN NO_DATA_FOUND THENRETURN '员工不存在';
END get_employee_name;
/
二、函数参数模式
| 模式 | 描述 | 示例 | 调用 |
| IN | 只读参数(默认) 输入值{可以不用写} | p_id IN NUMBER | sql调用 |
| OUT | 只写参数 输出值/*必须写*/ | p_result OUT VARCHAR2 | plsql调用 |
| IN OUT | 可读写参数 既输入也输出 | p_counter IN OUT NUMBER | plsql调用 |
| sys_refcursor | 动态游标 | ||
| dbms_output.put_line | 输出 |
三、无参数:没有输入输出
--创建函数
create or replace function π return number as
begin return ACOS(-1);
end;--使用函数,求半径为1的圆的面积
select π*1*1 from dual
四、有参数:只输入IN--用select调用
【举例】
--手动制作一个函数sign()
--创建create or replace function mysign(v1 in number) return number asbeginif v1 > 0 thenreturn 1;/*这里的意思是输出一个表*/elsif v1 < 0 thenreturn - 1;elsereturn 0;end if;end;
/
--调用
select mysign(23333333) from dual--只输入用select
/*############################################################################*/【例题】
/*=====================================================================================*/
【1】制作一个函数,输入一个数值,返回它的相反数
--创建
CREATE OR REPLACE FUNCTION FUN_XFS(V1 NUMBER) RETURN NUMBER AS
BEGINIF V1 > 0 THENRETURN '-' || V1;ELSIF V1 < 0 THENRETURN ABS(V1);ELSERETURN 0;END IF;
END;
/
--引用
SELECT fun_xfs(0) FROM dual--调用
CREATE OR REPLACE FUNCTION FUN_XFS1(V1 NUMBER) RETURN NUMBER AS
BEGINRETURN(-V1);
END;
/
--调用
SELECT fun_xfs1(-1) FROM dual
/*=====================================================================================*/
【2】编写一个函数,输入一个员工编号,返回其工资等级
--创建
create or replace function 工资等级1(v1 number) return number asv_g salgrade.grade%type;
beginselect b.gradeinto v_gfrom emp a, salgrade bwhere a.empno = v1and a.sal between b.losal and b.hisal;return v_g;
end;
/
--调用
select 工资等级1(7788) from dual
----------------------------------------------
--创建
create or replace function 工资等级2(v1 number) return number asv_g salgrade.grade%type;
beginselect b.gradeinto v_gfrom emp ainner join salgrade bon a.sal between b.losal and b.hisalwhere a.empno = v1;return v_g;
end;
/
--调用
select 工资等级2(7788) from dual
select 查询工资等级(7369) from dual--有输入,
没有 dnms_output.put_line()输出,用select调用/*=====================================================================================*/
【3】输入一个日期,返回这个月有多少个周一
--创建
create or replace function fun_3(v1 date) return number asv2 number;
beginselect count(trunc(v1, 'mm') - 1 + level)into v2from dualwhere to_char((trunc(v1, 'mm') - 1 + level), 'd') = 2 connect by level <= to_char(last_day(v1), 'dd');return v2;
end;----有输入,没有 dnms_output.put_line()输出,用select调用
/
--调用
select fun_3(date'2019-4-1') from dual
--------------------------------------------------------------------
--创建
create or replace function 某月有多少周一(v1 date) return number asv_count number;
beginselect count(mm)into v_countfrom (select level + (trunc(v1, 'mm') - 1) mmfrom dualconnect by level <= to_char(last_day(v1), 'dd'))where to_char(mm, 'd') = 2;return v_count;
end;
/
--调用
select 某月有多少周一(date'2019-01-02') from dual/*=====================================================================================*/
【4】输入一个部门编号和日期,返回这个部门在这个日期之后入职的员工人数
--创建
CREATE OR REPLACE FUNCTION FUN_4(V1 NUMBER, V2 DATE) RETURN NUMBER ASV3 NUMBER;
BEGINSELECT COUNT(*)INTO V3FROM EMPWHERE DEPTNO = V1AND HIREDATE > V2;RETURN V3;
END;
/
--调用
SELECT fun_4(10,DATE'1981-12-01') FROM dual
五、有参数:有输出OUT--plsql调用
1、输出变量
【举例】
CREATE OR REPLACE FUNCTION calculate_tax(p_salary IN NUMBER,p_tax_rate OUT NUMBER
) RETURN NUMBER
ISv_tax_amount NUMBER;
BEGINIF p_salary <= 5000 THENp_tax_rate := 0;ELSIF p_salary <= 10000 THENp_tax_rate := 0.1;ELSEp_tax_rate := 0.2;END IF;v_tax_amount := p_salary * p_tax_rate;RETURN v_tax_amount;
END calculate_tax;
/-- 调用示例
DECLAREv_rate NUMBER;v_tax NUMBER;
BEGINv_tax := calculate_tax(15000, v_rate);DBMS_OUTPUT.PUT_LINE('税率: ' || v_rate || ', 税额: ' || v_tax);
END;
/【练习】
/*=====================================================================================*/
【1】输入一个部门编号获取部门的工资总和和总人数
-- 创建
create or replace function fun3(v1 number, v_sum out number)
return number asv_count number;
beginselect sum(sal), count(*) into v_sum, v_count from emp where deptno = v1;return v_count;
end;
-- 调用
declarev_sum number;v_count number;
beginv_count := fun3(10, v_sum);--给返回值赋值:=fun_name(参数,参数)dbms_output.put_line('总工资:' || v_sum || ' 总人数:' || v_count);
end;
//*=====================================================================================*/
【2】输入一个员工编号,输出它的月薪和职位
-- 创建create or replace function 查询月薪和职位(v1 number, v_s out number)return varchar2 asv_j varchar2(20);beginselect e.sal,e.job into v_s,v_j from emp e where e.empno = v1;return v_j;end;
-- 调用declarev_s number;v_j varchar2(20);beginv_j:=查询月薪和职位(&a,v_s);dbms_output.put_line('月薪'||v_s||'职位'||v_j);
end;
//*=====================================================================================*/
【2】输入一个工资等级,输出这个等级的最低工资,最高工资
CREATE OR REPLACE FUNCTION FUN_5(V1 NUMBER, V2 OUT NUMBER) RETURN NUMBER ASV3 NUMBER;
BEGINSELECT LOSAL, HISAL INTO V2, V3 FROM SALGRADE WHERE GRADE = V1;RETURN V3;
END;
/
-- 调用示例
DECLAREV1 NUMBER := &A;V2 NUMBER;V3 NUMBER;
BEGINV3 := FUN_5(V1, V2);DBMS_OUTPUT.PUT_LINE('最低工资' || V2 || CHR(10) || '最高工资' || V3);
END;
/
2、输出游标
-------------------------
(一)【返回一个动态游标】
-------------------------
【1】输入一个部门编号,输入部门员工信息,
--创建
create or replace function fun4(v1 number) return sys_refcursor ascur_emp sys_refcursor;
beginopen cur_emp forselect * from emp where deptno =v1;return cur_emp;
end;
--调用
declarecur_a sys_refcursor;v_emp emp%rowtype;
begincur_a := fun4(&a);loopfetch cur_ainto v_emp;exit when cur_a%notfound;dbms_output.put_line(v_emp.empno || v_emp.ename);end loop;
end;/*#####################################################################################*/
-------------------------------
(二)【输出和返回都是动态游标】
-------------------------------
【1】输入一个部门编号,输出这个部门的员工信息和部门信息
--创建
create or replace function fun5(v1 number, cur_dept out sys_refcursor)--输出是动态游标return sys_refcursor as--返回是动态游标cur_emp sys_refcursor;
beginopen cur_emp forselect * from emp where deptno = v1;open cur_dept forselect * from dept where deptno = v1;return cur_emp;
end;
--调用
declarecur_emp sys_refcursor;cur_dept sys_refcursor;v_emp emp%rowtype;v_dept dept %rowtype;
begincur_emp := fun5(20, cur_dept);loopfetch cur_empinto v_emp;exit when cur_emp%notfound;dbms_output.put_line(v_emp.empno || v_emp.ename || v_emp.deptno);end loop;loopfetch cur_dept into v_dept;exit when cur_dept%notfound;dbms_output.put_line(v_dept.deptno || v_dept.dname);end loop;
end;【2】输入一个经理编号,输出他所有的下级姓名和员工编号和他自己的员工编号、入职日期
--创建
create or replace function fun6(v1 number, cur_1 out sys_refcursor)return sys_refcursor ascur_2 sys_refcursor;
beginopen cur_1 forselect empno, ename from emp where mgr = v1;open cur_2 forselect empno, hiredate from emp where empno = v1;return cur_2;
end;
--调用
declarecur_1 sys_refcursor;cur_2 sys_refcursor;v1 emp.empno%type;v2 varchar2(20);v3 number;v4 date;
begincur_2 := fun6(&a, cur_1);loopfetch cur_1into v1, v2;exit when cur_1%notfound;dbms_output.put_line('下级编号:' || v1 || '下级姓名:' || v2);end loop;loopfetch cur_2into v3, v4;exit when cur_2%notfound;dbms_output.put_line('经理编号:' || v3 || '入职日期:' || v4);end loop;
end;
六、有参数:有输入输出值IN OUT--必须用宏代换&
--创建
create or replace function fun7(v_empno number, v_jia in out number)return varchar2 asv_name emp.ename%type;
beginupdate emp001set sal = sal + v_jiawhere empno = v_empnoreturning ename, sal into v_name, v_jia;return v_name;
end;
--调用
declarev_empno emp.empno%type := &empno;---必须用宏代换v_name emp.ename%type;v_jia emp.sal%type := &jia;
beginv_name := fun7(v_empno, v_jia);dbms_output.put_line('姓名:' || v_name || '新工资:' || v_jia);
end;
七、函数返回值
1. 返回标量值
CREATE OR REPLACE FUNCTION get_department_name(p_dept_id IN departments.department_id%TYPE
) RETURN VARCHAR2
ISv_dept_name departments.department_name%TYPE;
BEGINSELECT department_name INTO v_dept_nameFROM departmentsWHERE department_id = p_dept_id;RETURN v_dept_name;
EXCEPTIONWHEN NO_DATA_FOUND THENRETURN '部门不存在';
END get_department_name;
/
2. 返回复合类型
(1)使用%ROWTYPE
CREATE OR REPLACE FUNCTION get_employee_info(p_emp_id IN employees.employee_id%TYPE
) RETURN employees%ROWTYPE
ISv_emp employees%ROWTYPE;
BEGINSELECT * INTO v_empFROM employeesWHERE employee_id = p_emp_id;RETURN v_emp;
EXCEPTIONWHEN NO_DATA_FOUND THENRETURN NULL;
END get_employee_info;
/
(2)使用自定义类型
-- 先创建对象类型
CREATE OR REPLACE TYPE emp_obj AS OBJECT (emp_id NUMBER,emp_name VARCHAR2(100),salary NUMBER,hire_date DATE
);
/-- 创建返回对象的函数
CREATE OR REPLACE FUNCTION get_employee_obj(p_emp_id IN NUMBER
) RETURN emp_obj
ISv_emp emp_obj;
BEGINSELECT emp_obj(employee_id, first_name || ' ' || last_name,salary,hire_date) INTO v_empFROM employeesWHERE employee_id = p_emp_id;RETURN v_emp;
END get_employee_obj;
/
八、函数中的DML操作
函数可以包含DML操作,但有以下限制:
-
不能执行事务控制语句(COMMIT/ROLLBACK)
-
调用时可能需要特殊权限
示例:审计函数
CREATE OR REPLACE FUNCTION update_salary_with_log(p_emp_id IN employees.employee_id%TYPE,p_new_salary IN employees.salary%TYPE
) RETURN VARCHAR2
ISv_old_salary employees.salary%TYPE;v_result VARCHAR2(100);
BEGIN-- 获取旧薪资SELECT salary INTO v_old_salaryFROM employeesWHERE employee_id = p_emp_id;-- 更新薪资UPDATE employeesSET salary = p_new_salaryWHERE employee_id = p_emp_id;-- 记录审计日志INSERT INTO salary_audit (audit_id, employee_id, old_salary, new_salary, change_date) VALUES (audit_seq.NEXTVAL, p_emp_id,v_old_salary, p_new_salary,SYSDATE);v_result := '薪资从 ' || v_old_salary || ' 更新为 ' || p_new_salary;RETURN v_result;
EXCEPTIONWHEN OTHERS THENRETURN '错误: ' || SQLERRM;
END update_salary_with_log;
/
九、确定性函数与并行处理
1. 确定性函数(DETERMINISTIC)
对于相同输入总是返回相同结果的函数可以声明为DETERMINISTIC,提高性能:
CREATE OR REPLACE FUNCTION calculate_bonus(p_salary IN NUMBER,p_years IN NUMBER
) RETURN NUMBER DETERMINISTIC
IS
BEGINRETURN p_salary * p_years * 0.01;
END calculate_bonus;
/
2. 并行处理(PARALLEL_ENABLE)
CREATE OR REPLACE FUNCTION process_large_data(p_input IN NUMBER
) RETURN NUMBER PARALLEL_ENABLE
IS
BEGIN-- 复杂计算RETURN p_input * 2;
END process_large_data;
/
十、管道表函数(PIPELINED)
返回结果集的函数,可以逐行返回数据:
1. 基本管道函数
-- 创建集合类型
CREATE OR REPLACE TYPE emp_table_type AS TABLE OF emp_obj;
/-- 创建管道函数
CREATE OR REPLACE FUNCTION get_dept_employees(p_dept_id IN NUMBER
) RETURN emp_table_type PIPELINED
IS
BEGINFOR emp_rec IN (SELECT employee_id, first_name, last_name, salary, hire_dateFROM employeesWHERE department_id = p_dept_id) LOOPPIPE ROW(emp_obj(emp_rec.employee_id,emp_rec.first_name || ' ' || emp_rec.last_name,emp_rec.salary,emp_rec.hire_date));END LOOP;RETURN;
END get_dept_employees;
/-- 调用示例
SELECT * FROM TABLE(get_dept_employees(10));
2. 带参数的管道函数
CREATE OR REPLACE FUNCTION filter_employees(p_min_sal IN NUMBER DEFAULT 0,p_max_sal IN NUMBER DEFAULT 999999
) RETURN emp_table_type PIPELINED
IS
BEGINFOR emp_rec IN (SELECT employee_id, first_name, last_name, salary, hire_dateFROM employeesWHERE salary BETWEEN p_min_sal AND p_max_sal) LOOPPIPE ROW(emp_obj(emp_rec.employee_id,emp_rec.first_name || ' ' || emp_rec.last_name,emp_rec.salary,emp_rec.hire_date));END LOOP;RETURN;
END filter_employees;
/-- 调用示例
SELECT * FROM TABLE(filter_employees(5000, 10000));
十一、函数的调用方式
1. 在PL/SQL中调用
DECLAREv_name VARCHAR2(100);v_tax NUMBER;
BEGINv_name := get_employee_name(100);v_tax := calculate_tax(8000);DBMS_OUTPUT.PUT_LINE(v_name || '的税额: ' || v_tax);
END;
/
2. 在SQL语句中调用
-- 在SELECT中使用
SELECT employee_id, get_employee_name(employee_id) AS full_name,calculate_bonus(salary, 5) AS bonus
FROM employees
WHERE department_id = 10;-- 在WHERE条件中使用
SELECT * FROM employees
WHERE calculate_tax(salary) > 1000;-- 在ORDER BY中使用
SELECT * FROM employees
ORDER BY calculate_bonus(salary, years_of_service) DESC;
3. 在DML语句中调用
-- 在INSERT中使用
INSERT INTO employee_audit
VALUES (audit_seq.NEXTVAL, get_employee_name(100),SYSDATE);-- 在UPDATE中使用
UPDATE employees
SET salary = salary + calculate_bonus(salary, years_of_service)
WHERE employee_id = 100;
十二、函数的管理与维护
1. 查看函数定义
-- 查看源代码
SELECT text FROM user_source
WHERE name = 'GET_EMPLOYEE_NAME'
ORDER BY line;-- 查看函数状态
SELECT object_name, status
FROM user_objects
WHERE object_type = 'FUNCTION';
2. 重新编译函数
ALTER FUNCTION function_name COMPILE;
3. 删除函数
DROP FUNCTION function_name;
4. 函数权限控制
-- 授予执行权限
GRANT EXECUTE ON get_employee_name TO user1;-- 创建公有同义词
CREATE PUBLIC SYNONYM get_emp_name FOR hr.get_employee_name;
十三、函数设计最佳实践
1. 单一职责原则:
- 每个函数只完成一个明确的任务
2. 合理命名:
- 使用动词+名词形式,如
calculate_tax、get_employee_name
3. 参数设计:
- 限制参数数量(通常不超过5个)
- 使用默认参数减少重载
- 避免使用OUT参数(影响可读性)
4. 错误处理:
- 捕获并处理预期异常
- 对意外异常提供有意义的错误信息
5. 性能考虑:
- 对频繁调用的函数使用DETERMINISTIC
- 避免在函数中执行复杂SQL
- 考虑使用管道函数处理大数据集
6. 文档注释:
CREATE OR REPLACE FUNCTION calculate_tax(p_salary IN NUMBER -- 输入:员工薪资
) RETURN NUMBER -- 返回:计算出的税额
IS
/*
* 功能: 根据薪资计算应缴税额
* 逻辑:
* - 5000以下: 免税
* - 5000-10000: 10%
* - 10000以上: 20%
* 创建: 2023-01-01
* 作者: DBA
*/
BEGIN-- 函数实现
END;
/
十四、高级函数特性(了解)
1. 函数重载(在包中)
关于包的内容会在后面详细讲到
CREATE OR REPLACE PACKAGE employee_pkg AS-- 根据ID获取员工名FUNCTION get_name(p_emp_id IN NUMBER) RETURN VARCHAR2;-- 根据邮箱获取员工名FUNCTION get_name(p_email IN VARCHAR2) RETURN VARCHAR2;
END employee_pkg;
/CREATE OR REPLACE PACKAGE BODY employee_pkg ASFUNCTION get_name(p_emp_id IN NUMBER) RETURN VARCHAR2 ISv_name VARCHAR2(100);BEGINSELECT first_name || ' ' || last_name INTO v_nameFROM employeesWHERE employee_id = p_emp_id;RETURN v_name;END;FUNCTION get_name(p_email IN VARCHAR2) RETURN VARCHAR2 ISv_name VARCHAR2(100);BEGINSELECT first_name || ' ' || last_name INTO v_nameFROM employeesWHERE email = p_email;RETURN v_name;END;
END employee_pkg;
/
2. 递归函数
CREATE OR REPLACE FUNCTION factorial(p_num IN NUMBER
) RETURN NUMBER
IS
BEGINIF p_num <= 1 THENRETURN 1;ELSERETURN p_num * factorial(p_num - 1);END IF;
END factorial;
/-- 调用示例
SELECT factorial(5) FROM dual; -- 返回120
3. 使用上下文函数(12c+)
CREATE OR REPLACE FUNCTION get_session_user
RETURN VARCHAR2
ACCESSED UNDER CURRENT_USER
IS
BEGINRETURN SYS_CONTEXT('USERENV', 'SESSION_USER');
END;
/
自定义函数是Oracle PL/SQL编程的核心组件,合理设计和使用函数可以显著提高代码的可重用性、可维护性和性能。
相关文章:
Oracle数据库数据编程SQL<3.4 PL/SQL 自定义函数>
自定义函数是Oracle数据库中可重用的PL/SQL代码块,它接受参数、执行操作并返回一个值。函数可以在SQL语句中直接调用,极大增强了SQL的处理能力。 分类调用没有参数没有输入输出写SQL不加参数有参数有输入无输出写SQL加参数无输入有输出输出变量写PL/SQL…...
【Ubuntu常用命令】
1.将本地服务器文件或文件夹传输到远程服务器 文件 scp /data/a.txt administrator10.60.51.20:/home/administrator/ 文件夹 scp -r /data/ administrator10.60.51.20:/home/administrator/ 2.从远程服务器传输文件到本地服务器 scp administrator10.60.51.20:/data/a.txt /h…...
PyTorch图像预处理--Compose
torchvision.transforms.Compose 是 PyTorch 中用于图像预处理的核心工具,可将多个图像变换操作组合成一个顺序执行的流水线。 1. 定义与作用 功能:将多个图像处理步骤(如缩放、裁剪、归一化等)串联为一个整体ÿ…...
从DeepSeek到Qwen,AI大模型的移植与交互实战指南
在不久前发布的《技术实战 | OK3588-C开发板上部署DeepSeek-R1大模型的完整指南》一文中,小编为大家介绍了DeepSeek-R1在飞凌嵌入式OK3588-C开发板上的移植部署、效果展示以及性能评测,本篇文章不仅将继续为大家带来关于DeepSeek-R1的干货知识࿰…...
SkyWalking+Springboot实战
1、下载SkyWalking APM 1.手动下载 Downloads | Apache SkyWalkinghttps://skywalking.apache.org/downloads/ 2.链接下载 https://dlcdn.apache.org/skywalking/10.2.0/apache-skywalking-apm-10.2.0.tar.gzhttps://dlcdn.apache.org/skywalking/10.2.0/apache-skywalking-…...
算法 | 河马优化算法原理,公式,应用,算法改进及研究综述,matlab代码
以下是关于河马优化算法(Hippopotamus Optimization Algorithm, HO)的完整综述,包含原理、公式、应用场景、改进方向及可直接运行的 Matlab 完整代码。一、算法原理 河马优化算法(HO)由Amiri等人于2024年提出,是受河马群体行为启发的元启发式算法,其核心基于以下三阶段行…...
org.apache.maven.surefire:surefire-junit-platform:jar:2.22.2 Maven打包失败
org.apache.maven.surefire:surefire-junit-platform:jar:2.22.2 解决办法 勾上这个,打包时跳过测试代码...
nginx-rtmp-module之ngx_rtmp_live_module.c代码详解
ngx_rtmp_live_module.h 头文件分析 这个头文件定义了直播模块相关的结构体、函数声明和一些常量,主要用于支持 RTMP 协议中的直播流。 1. 核心数据结构: ngx_rtmp_live_chunk_stream_t: 该结构体用于表示一个数据流中的“块”,…...
【MVCC快照如何实现】
MVCC(多版本并发控制)快照的实现原理 MVCC(Multi-Version Concurrency Control)是现代数据库实现事务隔离级别的核心技术,它通过数据多版本和快照机制来实现高效的并发控制。下面我将详细解析MVCC快照的实现机制。 一、MVCC核心组件 1. 版本链结构 MVCC通过以下…...
在机器人和无人机时代,测绘人的出路在哪里?
一、技术革命:当测绘行业按下“加速键” 无人机与机器人技术正在重塑测绘行业的底层逻辑。传统测绘依赖人工作业,效率低、成本高且风险大,而无人机凭借其灵活性和高效性,已能快速完成大范围地形测绘,精度可达厘米级&a…...
linux》》docker 、containerd 保存镜像、打包tar、加载tar镜像
Linux》》docker: 默认情况下,Docker镜像保存在/var/lib/docker/目录下。 当您使用docker pull命令从Docker Hub或私有镜像仓库中拉取镜像时,Docker会自动将镜像文件保存在/var/lib/docker/image/目录下。 每个镜像都由一个或多个层组成,这些…...
DeepSeek+Kimi:PPT制作的效率革命
摘要:传统PPT制作面临模板选择困难、内容逻辑混乱、设计排版能力有限以及反复修改等问题。DeepSeek和Kimi两款AI工具的组合为PPT制作提供了全新的解决方案。DeepSeek擅长内容生成与逻辑推理,能够快速生成高质量的PPT大纲和内容;Kimi则专注于长…...
电影交流|基于Java+vue的电影交流平台小程序系统(源码+数据库+文档)
电影交流平台 目录 基于SprinBootvue的电影交流平台小程序系统 一、前言 二、系统设计 三、系统功能设计 1用户信息管理 2 电影信息管理 3公告信息管理 4论坛信息管理 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取&…...
深度学习入门(二):从感知机到神经网络
文章目录 前言一个神经网络的例子激活函数登场3层神经网络的实现矩阵运算3层神经网络示意图符号定义第一层信号传递第二层信号传递第三层信号传递 代码实现实践:手写数字识别参考资料 前言 上一篇文章我们学习了感知机,因为它和神经网络有很多共同点&am…...
Sentinel 相关知识点
Sentinel 实现原理? Sentinel 是面向分布式服务架构的流量控制组件,主要以流量为切入点,从限流、流量整形、熔断降级、系统负载保护等多个维度来帮助开发者保障微服务的稳定性。以下是 Sentinel 的实现原理: 核心概念 资源&…...
AI三大主义 和 深度学习三大主义
在人工智能(AI)研究领域,"三大主义"通常指三种核心方法论或思想流派,它们代表了不同的技术路径和哲学观点。以下是主流的划分方式: 1. 符号主义(Symbolicism) 核心思想:智…...
探索 Vue 中的多语言切换:<lang-radio /> 组件详解!!!
探索 Vue 中的多语言切换:<lang-radio /> 组件详解 🌍 嗨,大家好!👋 今天我们来聊聊如何在 Vue 项目中实现一个优雅的多语言切换功能——<lang-radio /> 组件。这是一个小而美的组件,出现在登…...
安卓的布局方式
一、RelativeLayout 相对布局 特点:每个组件相对其他的某一个组件进行定位。 (一)主要属性 1、设置和父组件的对齐: alignParentTop : 设置为true,代表和父布局顶部对齐。 其他对齐只需要改变后面的Top为 Left、Right 或者Bottom&…...
Kotlin基础知识学习(五)
Lambda表达式 Lambda表达式是一种简洁的方式来定义匿名函数。Kotlin的Lambda表达式非常灵活,常用于函数式编程、集合操作、高阶函数等场景。 无参数的Lambda表达式 格式:{函数体} 调用:{函数体}() val greet { println("Hello, Kotl…...
搭建私人对外git空间
# 创建用户,指定不可登录的 Shell(git-shell 或 /usr/sbin/nologin) sudo adduser --system --shell /usr/bin/git-shell --group git # 验证用户配置 grep git /etc/passwd # 预期输出:git:x:998:998::/home/git:/usr/bin/git-s…...
5种特效融合愚人节搞怪病毒
内容供学习使用,不得转卖,代码复制后请1小时内删除,此代码会危害计算机安全,谨慎操作 并在虚拟机里运行此代码!,病毒带来后果自负! #include <windows.h> #include <cmath> #include <thread> using namespace std; // 屏幕特效函数声明 void In…...
DeepSeek本地部署(linux)
一、下载并安装Ollama 1.下载Ollama Ollama官网:Ollama 点击"Download",会跳转至下载页面。 1.1在线下载安装 可复制此命令到Linux服务器进行在线下载,如下载速度过慢,可选择离线下载安装。 curl -fsSL https://ollama.com/install.sh | sh1.2离线下载安装 …...
MySQL的基础语法1(增删改查、DDL、DML、DQL和DCL)
目录 一、基本介绍 二、SQL通用语法 三、SQL分类(DDL、DML、DQL、DCL) 1.DDL 1.1数据库操作 1.2表操作 1.2.1表操作-查询创建 1.2.2表操作-数据类型 1)数值类型 2)字符串类型 3)日期时间类型编辑 4)表操作-案例 1.2.3…...
Oracle数据库数据编程SQL<3.3 PL/SQL 游标>
游标(Cursor)是Oracle数据库中用于处理查询结果集的重要机制,它允许开发者逐行处理SQL语句返回的数据。 目录 一、游标基本概念 1. 游标定义 2. 游标分类 二、静态游标 (一)显式游标 【一】不带参数,普通的显示游标 1. 显式…...
畅享电脑流畅运行:深度卸载、智能监视与空间释放
软件介绍 在数字化办公与娱乐高度融合的当下,电脑承载着我们诸多重要任务,然而,随着软件的频繁安装与卸载,系统逐渐被各种顽固软件及其残留 “拖垮”,运行速度变慢、磁盘空间告急等问题接踵而至。别愁,今天…...
R --- Error in library(***) : there is no package called ‘***’ (服务器非root用户)
步骤 步骤一:在自己目录下创建R包安装路径步骤二:配置用户本地的R库路径步骤三:安装缺失的包(在终端)步骤四:验证安装 步骤一:在自己目录下创建R包安装路径 mkdir -p ~/R_libs步骤二࿱…...
Visual Studio Code 无法打开源文件解决方法
🌈 个人主页:Zfox_ 🔥 系列专栏:Linux 🔥 系列专栏:C从入门到精通 目录 一:🔥 突发状况 二:🔥 共勉 一:🔥 突发状况 🐬…...
核函数(机器学习深度学习)
一、核函数的基本概念 核函数(Kernel Function) 是机器学习中处理非线性问题的核心工具,通过隐式映射将数据从原始空间转换到高维特征空间,从而在高维空间中实现线性可分或线性建模。其数学本质是计算两个样本在高维空间中的内积…...
【工具】BioPred一个用于精准医疗中生物标志物分析的 R 软件包
介绍 R 语言包 BioPred 提供了一系列用于精准医疗中的亚组分析和生物标志物分析的工具。它借助极端梯度提升(XGBoost)算法,并结合倾向得分加权和 A 学习方法,帮助优化个体化治疗规则,从而简化亚组识别过程。BioPred 还…...
【银河麒麟系统常识】命令:dotnet --list-sdks(列出已安装的 .NET SDK 版本)
命令: dotnet --list-sdks 功能 列出当前系统中所有已安装的 .NET SDK 版本; 返回值规则 # 1. 格式:<版本号>[<安装路径>]; # 2. 排序:按版本号从低到高排序;示例...
