学习大数据DAY16 PLSQL基础语法5

news2024/11/15 7:06:14

目录

异常

自定义异常的格式

raise_application_error

处理异常

预定义异常

SQLcode和SQLerrm

非预定义异常

作业

触发器

触发器基本概念

DML触发器

DML触发器使用

instead of 触发器

管理触发器

作业2

函数、过程和包

函数

过程

参数

1. in 参数

2.out 参数

3. in out 参数

函数和过程的区别

过程优点

过程缺点

作业3

遗忘点复习

后面预告

异常

在PL/SQL中系统错误都由程序异常统一对待。一个异常一般属于以下情况:

●系统错误(内存溢出,索引重复)

●用户动作导致的错误

●应用程序向用户发出的警告

异常分成三大类:预定义异常、非预定义异常、自定义异常

处理方法分为:直接抛出异常、内部块处理异常、游标处理异常

预定义异常:由PL/SQL定义的异常。由于它们已在standard包中预定义了,因此,这些预定义异常可以直接在程序中使用,而不必再定义部分声明。

非预定义异常:用于处理预定义异常所不能处理的Oracle错误。

自定义异常:用户自定义的异常,需要在定义部分声明后才能在可执行部分使用。用户自定义异常对应的错误不一定是Oracle错误,例如它可能是一个数据错误。

三种异常中,预定义与非预定义异常都与Oracle错误有关,并且由Oracle隐含自动抛出,而自定义异常与Oracle错误没有任何关联,由开发人员为特定情况所定义的异常,需要显式抛出(raise)。

PL/SQL使用一个异常处理框架在跟踪并对错误进行响应。异常分为系统异常和程序员自定义异常。系统异常通常都有一个名称。自定义异常则使用exception_init指令给oracle指定名称,或使用raise_application_error 给这个错误指定错误编号和描述。

自定义异常的格式

声明异常

声明异常的格式:

异常名称 exception;

抛出异常

声明异常后在程序中抛出异常。

RAISE 异常名;

RAISE 包名.异常名称;

RAISE;

第一种是抛出当前块异常,第二种是抛出当前包异常,这种方式能够实现在包外进行异常的抛出。第三种不需要异常名称,用于在异常中抛出异常,实现异常传播的目的。

raise_application_error

该过程用于自定义错误信息,仅限数据库端子程序使用(过程、函数、包、触发器),不能在匿名块或客户端子程序中。

格式:

raise_application_error(error_number,mesage[,[true|false]]);

其中error_number定义错误号,必须是-20000到-20999之间的负整数;message指定错误信息,不长于2048字节; 第三个为可选参数,true则错误会被放在先前错误的堆栈中,false则替换先前所有错误,默认为false。

使用RAISE_APPLICATION_ERROR 抛出异常的好处在于可以给异常加上一段错误消息。

处理异常

当有异常抛出,当前代码块会终止执行,并跳转到异常处理单元,在异常处理单元

exception处理异常。

when 异常名称 [or 异常名称] then 处理语句;

when others then 处理语句;

预定义异常

Oracle根据程序可能报错的情况定义的一类异常,常见的Oracle预定义异常如下:

SQLcode和SQLerrm

sqlCode:是数据库操作的返回码。

sqlerrm:是数返回指定错误代码的错误信息。

在一个内在的异常中,SQLCODE返回Oracle错误的序号,而SQLERRM返回的是相应的错误消息,错误消息首先显示的是错误代码。SQLCODE返回的是负数,除非Oracle的错误为“ORA-01403:NO DATA FOUND”(译:ORA-01403:未找到数据),当Oracle错误为“ORA-01403:NO DATA FOUND”时,其对应的SQLCODE为+100。对于用户自定义的异常,SQLCODE返回的是+1,而SQLERRM返回的是User-Defined Exception。

sqlcode和sqlerrm是不能直接在sql语句中使用,必须先将其赋给变量后,才能在sql语句中使用

--预定义异常

declare

v_empno number;

begin

SELECT EMPNO INTO V_EMPNO from emp ;

exception

when TOO_MANY_ROWS then

dbms_output.put_line(sqlerrm||'-sql语句返回结果多余一行'||sqlcode);

end;

--多个异常

declare

v_empno number;

begin

SELECT EMPNO INTO V_EMPNO from emp where empno=2;

exception

when no_data_found then

dbms_output.put_line(sqlerrm ||'-啥也没有'||sqlcode);

when TOO_MANY_ROWS then

dbms_output.put_line(sqlerrm||'-sql语句返回结果多余一行'||sqlcode);

when others then

dbms_output.put_line(sqlerrm||'---------'||sqlcode);

end;

非预定义异常

非预定义异常用于处理与21个预定义异常无关的Oracle错误。 由于预定义异常只是与一部分Oracle错误相连的异常,所以如果要处理没有与预定义异常对应的Oracle错误时,则需要为这些Oracle错误声明相应的非预定义异常。

注意,通过exception_init,一个自定义异常只能和一个Oracle错误相连,在异常处理语句中, sqlcode和sqlerrm将返回这个Oracle错误的代码和消息文本,而不是返回用户自定义消息。 

--非预定义异常

declare

errorsql exception ;

pragma exception_init(errorsql,-2291);

begin

update emp set deptno= 55 where empno=7499;

exception

when errorsql then

dbms_output.put_line(sqlerrm||'输入的部门编号有误,查无此部门'||sqlcode);

end;

--自定义异常

declare

v_sal number:=&输入工资;

lowersal exception ;--声明一个异常名称

begin

if v_sal <2000 then

raise lowersal ;--抛出异常

else update emp set sal =v_sal where empno=&员工编号;

end if;

exception

when lowersal then --处理异常

dbms_output.put_line('你给的工资太低了 ,社保局要调查你的');

end;

作业

第一题乱写的,第二题抄的课件,第三题自己认真写的。

--1.练习预定义异常,多个异常和其他异常

declare

v_empno number;

begin

  SELECT EMPNO INTO V_EMPNO from emp ;

exception

  when others then

    dbms_output.put_line('杂鱼~代码都不会写的杂鱼~'); 

end;

--2.写一个触发员工表主键的非预定义异常

declare

errorsql exception ;

pragma exception_init(errorsql,-2291);

begin

update emp set deptno= 55 where empno=7499;

exception

when errorsql then

dbms_output.put_line(sqlerrm||'输入的部门编号有误,查无此部门'||sqlcode);

end;

--3.输入员工编号和要修改的工资,如果工资低于3000则抛出自定义异常

declare

v_empno emp.empno%type:=&输入员工编号;

v_sal emp.sal%type:=&输入要修改的工资;

RowSal exception;

begin

  if v_sal<3000 then

    raise RowSal;

   else

     update emp set sal=v_sal where empno=v_empno;

     end if;

  exception

    when RowSal then

      dbms_output.put_line('工资太低了,员工要活不下去啦!'); 

  end;

触发器

触发器使用场景:

●对表的修改进行验证

●数据库的自我维护

●通过不同方式对数据库活动进行规范

触发器触发场景:

●dml语句触发

●ddl语句触发

●数据库事件触发(如登录、退出、启动和关闭)

●instead of 触发(针对视图操作)

●挂起触发(语句运行中遇到空间问题挂起后触发)

触发器基本概念

before触发器:在触发场景执行前执行触发器语句

after触发器:在触发场景执行后执行触发器语句

语句级别触发器:触发场景以语句为单位进行触发(一个语句只触发一次)

行级别触发器:触发场景以记录为单位进行触发(每影响一行记录触发一次)

伪记录new:触发场景触发后记录的值

伪记录old:触发场景触发前记录的值

when语句:通过判断条件执行触发器 

DML触发器

dml触发器格式:

create or replace trigger 触发器名称

{before|after} --指明触发器实在语句执行前或之后进行处理

{insert|delete|update|update of 列名表} on 表名--指明触发器是在哪种DML语句中触发

[for each row]--指明语句会在处理每行记录是激活触发器,默认是只为整个语句激活一次

[when .....] --一个when语句来指明触发逻辑,避免一些错误执行

[declare]

触发器中禁用commit 、rollback。整个when语句需要用括号包裹,并且只能使用内置函

数,自定义函数无法引用,when语句只能用于行级别触发器,语句级无法使用when语

句。对于insert 语句,不存在 old伪记录;对于delete语句,不存在new伪记录。

DML触发器使用

DML触发器使用规范:

1. 触发器不接受参数。

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

3. 在一个表上的触发器越多,对在该表上的DML操作的性能影响就越大。--索引--约束--序列--

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

5. 在触发器的执行部分只能用DML语句(SELECT、INSERT、UPDATE、DELETE),不能使用DDL语句(CREATE、ALTER、DROP)。--隐式事务

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

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

8. 在触发器主体中不能申明任何clob和blob变量。新值new和旧值old也不能向表中的任何long和blob列。

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

instead of 触发器

针对视图操作的触发器

instead of insert

instead of update

instead of delete

create or replace trigger test_emp_trigger

instead of insert on view_emp

for each row

begin

insert into emp values(:new.empno,:new.enmame,:new.job,:new.mgr,:new.hiredate,:new.sal,:new.comm,:new.deptno);

insert into dept values(:new.deptno,:new.dname,:new.loc);

end;

管理触发器

禁用触发器

alter trigger 触发器名称 disable;

激活触发器

alter trigger 触发器名称 enable;

删除触发器

drop trigger 触发器名称;

create or replace trigger dml_emp_trigger

before

update or delete or insert on emp

for each row

begin

if updating then

dbms_output.put_line('更新了一条记录,更新内容为: 员工编号'

||:new.empno||'员工姓名'||:new.ename||'员工职位'||:new.job);

elsif deleting then

dbms_output.put_line('删除了一条记录,删除内容为: 员工编号'

||:old.empno||'员工姓名'||:old.ename||'员工职位'||:old.job);

elsif inserting then

dbms_output.put_line('插入了一条记录,插入内容为: 员工编号'

||:new.empno||'员工姓名'||:new.ename||'员工职位'||:new.job);

end if;

end;

select * from emp;

insert into emp values('9899','test','sale',9999,sysdate,3333,444,10);

update emp set sal=990 where empno=9899;

delete from emp where empno=9899;

--添加到emplog日志表中

create table emplog

(

id number(8),

time date,

type varchar2(6),

empno number(4)

)

create sequence seq_emplog_1

start with 1000

seq_emplog_1.nextval 

create or replace trigger dml_emp_trigger

before

update or delete or insert on emp

for each row

begin

if updating then

dbms_output.put_line('更新了一条记录,更新内容为: 员工编号'

||:new.empno||'员工姓名'||:new.ename||'员工职位'||:new.job);

insert into emplog values(seq_emplog_1.nextval,sysdate,'update',:new.empno);

elsif deleting then

dbms_output.put_line('删除了一条记录,删除内容为: 员工编号'

||:old.empno||'员工姓名'||:old.ename||'员工职位'||:old.job);

insert into emplog values(seq_emplog_1.nextval,sysdate,'delete',:old.empno);

elsif inserting then

dbms_output.put_line('插入了一条记录,插入内容为: 员工编号'

||:new.empno||'员工姓名'||:new.ename||'员工职位'||:new.job);

insert into emplog values(seq_emplog_1.nextval,sysdate,'add',:new.empno);

end if;

end; 

insert into emp values('5555','test','sale',9999,sysdate,3333,444,10);

update emp set sal=990 where empno=5555;

delete from emp where empno=5555;

select * from emplog ;

作业2

第二题乱写的,可无视。

--1、创建触发器对emp表进行增删改操作

create or replace trigger t_emp

before

insert or update or delete on emp

for each row

begin

  if inserting then

    dbms_output.put_line('有人偷偷插入数据');

    elsif updating then

      dbms_output.put_line('有人偷偷修改数据');  

      elsif deleting then

        dbms_output.put_line('有人偷偷删除数据'); 

  end;

--2、把上面的记录添加到表emplog中

create or replace trigger t_emp

before

insert or update or delete on emplog

for each row

begin

  if inserting then

    dbms_output.put_line('有人偷偷插入数据');

    elsif updating then

      dbms_output.put_line('有人偷偷修改数据');  

      elsif deleting then

        dbms_output.put_line('有人偷偷删除数据'); 

  end;

--3、查看oracle自带日志 (系统表:v$sql)

select * from v$sql;

函数、过程和包

函数

所谓函数是通过 return语句而不是 out 或in out 参数返回数据的模块。和过程的调用不同的是,前者可以作为一个可执行语句单独存在,而函数只能作为一个可执行语句的一部分,如表达式中的元素或声明时赋值。

函数格式:

create or replace function 函数名称[参数,参数,参数....]

return 返回数据类型

is

--计算两个数的和

create or replace function getSum(n1 in number,n2 in number)

return number

is

he number(4);

begin

he:=n1+n2;

return he;

end;

select getSum(3,5)from dual;

select getSum(3,5),upper('ttt') from dual;

--根据输入日期输出星期几

create or replace function f_day(da in varchar2)

return varchar2

is

d date :=to_date(da,'yyyymmdd');

begin

return to_char(d,'day');

end;

select f_day('20220518') from dual;

过程

所谓过程就是执行一个或多个动作的块。由于在PL/SQL中对于过程的是一个单独的可执

行语句,一个PL/SQL代码中可以只有一个过程调用语句。

过程的格式:

create or replace procedure 过程名称 (参数,参数,参数)

is

可以有0个或多个返回值,通过out参数来返回结果

过程的调用:

call 过程名();

declare

begin

过程名();

end;

示例:

--无输入参数无输出参数

create or replace procedure p1

is

begin

dbms_output.put_line('我的第一个过程');

end;

call p1();

declare

begin

dbms_output.put_line('ttt');

p1();

end;

参数

存储过程作用:执行效率和SQL 代码封装

1. in 参数

用于接收参数,在子程序内部,不能进行修改。默认的参数模式:in

-- 声明存储过程

create or replace procedure pro_in(p_num in number)

is

begin

dbms_output.put_line(p_num);

-- p_num:=10;-- 添加此行编译报错,in 参数不能赋值

end ;

-- 调用

declare

test number:=1;

begin

pro_in(test);

dbms_output.put_line(test);

end;

结果: 输出 两个 1 

2.out 参数

输出模式的参数,用于输出值,会忽略传入的值。在子程序内部可以对其进行修改。

调用时 参数需要使用变量.

-- 声明存储过程

create or replace procedure pro_out(p_num out number)

is

begin

dbms_output.put_line(p_num);

p_num:=10;

end;

-- 调用

declare

test number:=1;

begin

pro_out(test);

dbms_output.put_line(test);

end;

结果: 忽略输入的值,输出一个 空,和一个 10 

3. in out 参数

能接收传入的实参值;在子程序内部可以修改,可以输出

调用时 参数需要使用变量.

-- 声明存储过程

create or replace procedure pro_in_out(p_num in out number)

is

begin

dbms_output.put_line(p_num);

p_num:=10;

end ;

-- 调用

declare

test number:=1;

begin

pro_in_out(test);

dbms_output.put_line(test);

end;

结果: 输出一个 1 和 一个 10

--输入empno返回ename

create or replace procedure getName(eno in number,name1 out varchar2)

is

n number(4);

begin

n:=9;

dbms_output.put_line(n);

select ename into name1 from emp where empno=eno;

end;

declare

name1 varchar2(10);

begin

getName(7499,name1);

dbms_output.put_line(name1);

end;

--三个输入参数和两个输出参数 返回两个值

create or replace procedure

p2(n1 in number,n2 in number,he out number,ji in out number)

is

begin

dbms_output.put_line(he);

dbms_output.put_line(ji);

he:=n1+n2;

ji:=n1*n2;

dbms_output.put_line(he);

dbms_output.put_line(ji);

end;

declare

he number(4);

ji number(4):=0;

begin

p2(3,5,he,ji);

select getSum(3,6) into he from dual;

dbms_output.put_line(he);

dbms_output.put_line(ji);

p1();

end;

--改造猴子吃桃代码1

create or replace procedure taozi

is

tao number(4):=1;

begin

for i in reverse 1..9

loop

tao:=(tao+1)*2;

end loop;

dbms_output.put_line(tao);

end;

call taozi();

--改造猴子吃桃代码2

create or replace procedure chitao1(tao in out number)

is

begin

for i in reverse 1..9

loop

tao:=(tao+1)*2;

end loop;

end;

declare

tao number(4):=1;

begin

chitao1(tao);

dbms_output.put_line(tao);

end; 

函数和过程的区别

1、返回值的区别

函数有1个返回值,而存储过程是通过参数返回的,可以有多个或者没有

2、调用的区别,函数可以在查询语句中直接调用,而存储过程必须单独调用.

函数:一般情况下是用来计算并返回一个计算结果;

存储过程: 一般是用来完成特定的数据操作(比如修改、插入数据库表或执行某些DDL语句等等)

过程优点

1、存储过程可以一次编译多次使用。 存储过程只在创建时进行编译,之后的使用都不需要重新编译,这就提升了 SQL 的执行效率。

2、可以减少开发工作量。将代码封装成模块,实际上是编程的核心思想之一,这样可以把复杂的问题拆解成不同的模块,然后模块之间可以重复使用,在减少开发工作量的同时,还能保证代码的结构清晰。

3、存储过程的安全性强。我们在设定存储过程的时候可以设置对用户的使用权限,这样就和视图一样具有较强的安全性。

4、可以减少网络传输量。因为代码封装到存储过程中,每次使用只需要调用存储过程即可,这样就减少了网络传输量。

5、良好的封装性。在进行相对复杂的数据库操作时,原本需要使用一条一条的 SQL 语句,可能要连接多次数据库才能完成的操作,现在变成了一次存储过程,只需要连接一次即可

过程缺点

基于上面这些优点,不少大公司都要求大型项目使用存储过程,比如微软、IBM 等公司。但是国内的阿里并不推荐开发人员使用存储过程,这是为什么呢?

存储过程虽然有诸如上面的好处,但缺点也是很明显的。

1、可移植性差。存储过程不能跨数据库移植,比如在 MySQL、Oracle 和 SQL Server 里编写的存储过程,在换成其他数据库时都需要重新编写。

2、调试困难。只有少数 DBMS 支持存储过程的调试。对于复杂的存储过程来说,开发和维护都不容易。虽然也有一些第三方工具可以对存储过程进行调试,但要收费。

3、存储过程的版本管理很困难。比如数据表索引发生变化了,可能会导致存储过程失效。我们在开发软件的时候往往需要进行版本管理,但是存储过程本身没有版本控制,版本迭代更新的时候很麻烦。

4、它不适合高并发的场景。高并发的场景需要减少数据库的压力,有时数据库会采用分库分表的方式,而且对可扩展性要求很高,在这种情况下,存储过程会变得难以维护,增加数据库的压力,显然就不适用了。 

作业3

--1、函数输入一个日期,返回当前日期是星期几

create or replace function selectday(daytime in varchar2)

return varchar2

is

dd varchar2(10);

begin

  dd:=to_char(to_date(daytime,'yyyymmdd'),'day');

  return dd;

  end;

  

declare

daytime varchar2(10):='&输入一个日期';

n varchar2(10);

begin

  n :=selectday(daytime);

  dbms_output.put_line(n); 

  end;

--2、函数实现输入一个字符串,返回一个倒序的字符串,改写上机练习4.5

create or replace function reversestr(n in varchar2)

return varchar2

is

m varchar2(100);

begin

  for i in reverse 1..length(n)

    loop

      m:=m||substr(n,i,1);

      end loop;

  return m;

  end;

  

--3、写一个过程,输入员工编号,返回员工的工资和姓名

create or replace procedure esn(v_empno in out number)

is

type names is record(

ename emp.ename%type,

sal emp.sal%type

);

v names;

begin

select ename,sal into v from emp where empno=v_empno;

dbms_output.put_line(v.ename||' '||v.sal); 

end;



declare

v_empno emp.empno%type:=&输入员工编号;

begin

  esn(v_empno);

  end;





/*4、写一个过程,输入一个部门编号,返回该部门工资最高的员工的员工编号,不考虑并

列,用row_number开窗*/

create or replace procedure des(v_deptno in out number)

is

v_empno emp.empno%type;

begin

  select empno into v_empno from(

  select row_number()over(partition by deptno order by sal desc) r,empno,deptno from emp

  ) where r=1 and deptno=v_deptno;

  dbms_output.put_line(v_empno); 

  end;

  

declare

v_deptno emp.deptno%type:=&输入部门编号;

begin

  des(v_deptno);

  end;

  

--5、把上面两个过程配合使用实现输入部门编号显示该部门的最高工资和人员姓名

create or replace procedure des_and_esn(v_deptno in out number)

is

v_empno emp.empno%type;

begin

  select empno into v_empno from(

  select row_number()over(partition by deptno order by sal desc) r,empno,deptno from emp

  ) where r=1 and deptno=v_deptno;

  esn(v_empno);

  end;

  

declare

v_deptno emp.deptno%type:=&输入部门编号;

begin

  des_and_esn(v_deptno);

  end;

  

select empno,ename from emp;--验证用

遗忘点复习

Substr(字符串,n,m) 第n位开始截取,第m位结束。

例:

Substr(aaaabbbccc,-3,2) from dual 返回cc.

Substr(aaaabbbccc,1,3) from dual 返回3个a.

要多敲代码,刷题的同时不要脱离理论的学习。

后面预告

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

KALI使用MSF攻击安卓设备

这期是kali使用MSF进行安卓渗透的保姆级别教程&#xff0c;话不多说&#xff0c;直接开始。 准备材料&#xff1a; 1.装有kali的实体机或虚拟机&#xff08;这里用实体机进行演示&#xff09; 2.一台安卓10.0以下的手机 打开kali&#xff0c;先用ifconfig查看自己的kali IP地址…

MySQL第八次作业

一、备份与恢复作业&#xff1a; 创库,建表&#xff1a; CREATE DATABASE booksDB; use booksDB; CREATE TABLE books ( bk_id INT NOT NULL PRIMARY KEY, bk_title VARCHAR(50) NOT NULL, copyright YEAR NOT NULL ); CREATE TABLE authors …

Git提交了敏感信息,通过BFG工具撤回或修改很久之前已经提交的内容

Git 提交了敏感信息怎么办&#xff1f; 这篇文章的由来&#xff0c;由于自己在提交代码的时候不小心把服务器的ip地址&#xff0c;还有数据库的密码给push到github上面去了。那么问题来了&#xff0c;我这个已经是一个月之前的提交的呢&#xff0c;现在还能改吗&#xff1f;别…

SIM900发送中文短信的处理过程

SIM900发送中文短信的处理过程 1、短信中心号码处理: 短信中心号码可以使用ATCSCA?获取。 在获取之前&#xff0c;最好将设置使用GSM字符&#xff1a; ATCSCS"GSM" OK ATCSCA? CSCA: "8613800755500",145 OK 这样一来&#xff0c;我就得…

Python酷库之旅-第三方库Pandas(023)

目录 一、用法精讲 58、pandas.isnull函数 58-1、语法 58-2、参数 58-3、功能 58-4、返回值 58-5、说明 58-6、用法 58-6-1、数据准备 58-6-2、代码示例 58-6-3、结果输出 59、pandas.notna函数 59-1、语法 59-2、参数 59-3、功能 59-4、返回值 59-5、说明 5…

线程的复习

目录 大纲Java中的线程概念创建线程的方法线程的生命周期线程的同步和通信线程的优先级和调度线程的中断 案例 大纲 Java中的线程概念 在Java中&#xff0c;线程是操作系统能够进行运算调度的最小单位&#xff0c;它被包含在进程之中&#xff0c;是进程中实际运作的部分。一个…

python单测框架之pytest常见用法

单测框架的作用 测试发现&#xff1a;从多个文件中寻找测试用例。测试执行&#xff1a;按照一定顺序去执行并且生成结果。测试断言&#xff1a;判断最终结果与实际结果的差异。测试报告&#xff1a;统计测试进度、耗时、通过率&#xff0c;生成测试报告。 pytest简介 pytest是…

51单片机10(蜂鸣器介绍)

一、蜂鸣器介绍&#xff1a; 1、蜂鸣器是一种一体化结构的电子讯响器&#xff0c;采用直流电压供电&#xff0c;广泛应用于电子产品中作为发声器件。蜂鸣器主要分为压电式蜂鸣器和电磁式蜂鸣器。 &#xff08;1&#xff09;压电式蜂鸣器&#xff0c;它主要由多谐的一个增胀器…

Cyber Weekly #15

赛博新闻 1、OpenAI 绝密项目「草莓」首次曝光 据外媒路透社报道&#xff0c;OpenAI 内部正在一个代号为「草莓&#xff08;Strawberry&#xff09;」的项目中开发一种新的人工智能模型。该模型细节此前从未被报道过&#xff0c;而 OpenAI 正在努力证明该模型类型能够提供高级…

C++客户端Qt开发——信号和槽

三、信号和槽 1.信号和槽概述 在Qt中&#xff0c;用户和控件的每次交互过程称为一个事件。比如"用户点击按钮”是一个事件&#xff0c;"用户关闭窗口”也是一个事件。每个事件都会发出一个信号&#xff0c;例如用户点击按钮会发出"按钮被点击"的信号&…

ensp防火墙智能选举综合实验

实验要求&#xff1a; 实验图&#xff1a; 新增配置&#xff1a; 路由isp: 7&#xff1a; 保留ip操作&#xff1a; 一、DX区域&#xff1a; 1、源地址池配置&#xff1a; 2、nat策略&#xff1a; nat安全策略配置&#xff1a; 二、YD&#xff1a; 1、源地址池配置&#xf…

最值得推荐的10款Windows软件!

AI视频生成&#xff1a;小说文案智能分镜智能识别角色和场景批量Ai绘图自动配音添加音乐一键合成视频播放量破百万https://aitools.jurilu.com/1.音乐播放器——Dopamine Dopamine是一款音乐播放器&#xff0c;设计简洁美观。它支持多种音频格式&#xff0c;包括wav、mp3、ogg…

平衡树——AcWing 253. 普通平衡树

平衡树 定义 平衡树是一种自平衡的二叉搜索树&#xff0c;它在进行插入和删除操作后能够自动调整其结构&#xff0c;以保持树的高度尽可能低&#xff0c;从而保证树的查找、插入和删除操作能够在对数时间内完成。最著名的平衡树有AVL树和红黑树。 AVL树&#xff1a;是一种严格…

10月23-25日|2024年武汉袋式除尘展重磅来袭

2024第六届&#xff08;武汉&#xff09;国际袋式除尘技术与设备展览会 时间&#xff1a;2024年10月23-25日 地点&#xff1a;武汉国际文化博览中心 展会介绍&#xff1a; 2024第6届&#xff08;武汉&#xff09;国际袋式除尘技术与设备展览会将于2024年10月23-25日在武汉文…

Linux进程理解

一、进程的理解 首先我们知道我们的操作其实都是在运行程序&#xff0c;不仅是在windows上打开软件还是在Linux上执行指令&#xff0c;而程序存在于磁盘上&#xff0c;程序的要想运行就要把程序的代码和数据从磁盘加载到内存&#xff0c;那么到这一步是创建了一个进程吗&#…

c#中的特性

在C#中&#xff0c;特性&#xff08;Attributes&#xff09;是一种向程序元素&#xff08;如类、方法、属性等&#xff09;添加元数据的方式。特性可以用来提供关于程序元素的附加信息&#xff0c;这些信息可以在编译时和运行时被访问。 特性主要有以下几个用途&#xff1a; 提…

北京交通大学《深度学习》专业课,实验2-前馈神经网络

1. 源代码 见资源“北京交通大学《深度学习》专业课&#xff0c;实验2-前馈神经网络” 2. 实验内容 &#xff08;1&#xff09;手动实现前馈神经网络解决上述回归、二分类、多分类任务 分析实验结果并绘制训练集和测试集的loss曲线 &#xff08;2&#xff09;利用to…

GUI界面开发之tkinter(一)

Tkinter是一个内置的Python库&#xff0c;用于创建图形用户界面&#xff08;GUI&#xff09;。它提供了一组工具和小部件&#xff0c;用于创建窗口、对话框、按钮、菜单和其他GUI元素。 在本篇文章中&#xff0c;主要介绍了窗口等知识点。 大家好&#xff01;我是码银&#x1…

STM32MP135裸机编程:烧录程序到EMMC的方法

0 前言 STM32MP135支持多种启动方式&#xff0c;包括SD卡、NAND Flash、EMMC等&#xff0c;基于STM32MP135裸机的SD卡烧录操作方法我们之前已经介绍过&#xff0c;现在介绍的STM32MP135烧录到EMMC的方法又和前面烧录到SD卡的操作有所不同。本文将介绍基于STM32MP135&#xff0…

缓存的击穿及解决方案

定义及图解 缓存击穿的意思是对于设置了过期时间的key&#xff0c;缓存在某个时间点过期的时 候&#xff0c;恰好这时间点对这个Key有大量的并发请求过来&#xff0c;这些请求发现缓存过期一般都会从后端 DB 加载数据并回设到缓存&#xff0c;这个时候大并发的请求可能会瞬间把…