PL/SQL入门到实践

一、什么是PL/SQL

  1. PL/SQL是Procedural Language/Structured Query Language的缩写。
  2. PL/SQL是一种过程化编程语言,运行于服务器端的编程语言。
  3. PL/SQL是对SQL语言的扩展。PL/SQL结合了SQL语句和过程性编程语言的特性,可以用于编写存储过程、触发器、函数等数据库对象。它现在是Oracle数据库系统的核心语言,Oracle的许多部件都是由PL/SQL编写的。

二、PL/SQL特点

  1. 扩展性:PL/SQL是Oracle对SQL的扩展,增加了过程处理语句(控制结构),使SQL的功能更加强大。
  2. 过程化:PL/SQL不仅支持SQL的数据查询、数据操纵和数据定义功能,还具有强大的过程化功能。
  3. 块结构(模块化):PL/SQL是一种块结构的语言,组成PL/SQL程序的单元是逻辑块,每个块都可以划分为三个部分:声明部分、执行部分和异常处理部分。
  4. 可重用性:PL/SQL代码可以定义存储过程和函数,在客户端需要的时候可以调用,实现了模块的可重用性。
  5. 可移植性:PL/SQL代码可以使用任何ASCII文本编辑器编写,对任何Oracle能够运行的操作系统都非常便利。
  6. 改善性能(降低网络拥挤):PL/SQL是以整个语句块发给服务器,降低了网络拥挤,从而提高性能。因为SQL语句是以语句为单位进行发送的,在网络环境下会占用大量的服务器时间,可能导致网络拥挤。

三、PL/SQL的结构

PL/SQL 块概念

块(block)是 PL/SQL的基本程序单元,编写pl/sql程序实际上就是编写pl/sql块,要完成相对简单的应用功能,可能只需要编写一个pl/sql块,要完实现复杂的功能,可能需要再一个pl/sql块中嵌套其他的pl/sql块。

一个 PL/SQL 块通常由三个部分组成:声明部分、执行部分和异常处理部分。

PL/SQL 块的基本结构

DECLARE  -- 声明变量、常量、类型、游标等  
BEGIN  -- 执行 SQL 语句和 PL/SQL 语句  
EXCEPTION  -- 处理异常  
END;  

DECLARE 部分(可选)

在这一部分,你可以声明 PL/SQL 变量、常量、类型、游标、子程序等。这些声明的对象在 PL/SQL 块的其余部分(BEGIN...END 之间)是可见的。

示例:

DECLARE  v_name VARCHAR2(50);  
BEGIN  -- 使用变量...  
END;  

BEGIN 部分(必需)

这是 PL/SQL 块的主要部分,包含要执行的 SQL 语句和 PL/SQL 语句。你可以在这里对前面声明的变量进行赋值、执行查询、控制流语句(如 IF、LOOP、CASE 等)等。

DECLARE  v_name VARCHAR2(50);  
BEGIN  v_name := 'John Doe';  DBMS_OUTPUT.PUT_LINE('Hello, ' || v_name);  
END;  

EXCEPTION 部分(可选)

如果在 BEGIN...END 部分的代码执行过程中出现了异常(如除零错误、无效的 SQL 语句等),那么代码会跳转到 EXCEPTION 部分进行处理。在 EXCEPTION 部分,你可以捕获异常并编写相应的处理代码。

DECLARE  v_divisor NUMBER;  
BEGIN  v_divisor := 0;  DBMS_OUTPUT.PUT_LINE(10 / v_divisor); -- 这会引发一个异常  
EXCEPTION  WHEN ZERO_DIVIDE THEN  DBMS_OUTPUT.PUT_LINE('除数不能为零!');  
END;  

PL/SQL 块类型

  • 匿名块:没有名称的 PL/SQL 块,通常在 SQL*Plus 或其他工具中直接执行。
  • 子程序:包括存储过程和函数,它们有名称,可以在 PL/SQL 程序中调用。
  • 触发器:与数据库表事件关联的 PL/SQL 块,当满足特定条件时自动执行。
  • :将相关的 PL/SQL 类型、变量、常量、子程序等组合到一起的数据库对象。

四、PL/SQL中的标识符

标识符定义规范

pl/sql程序设计中的标识符定义与sql的标识符定义的要求相同。

  • 标识符名不能超过30字符
  • 第一个字符必须为字母
  • 不分大小写
  • 不能是sql保留字

变量推荐命名方法

五、PL/SQL块的数据类型

基本数据类型

基本数据类型使用

-- 声明变量
DECLAREv_name varchar2(100);v_id varchar2(100);v_number NUMBER :=1;--给变量赋值
BEGIN --主体部分SELECT name,loginid INTO v_name,v_id FROM TAUSER WHERE userid = '1';dbms_output.put_line(v_name||','||v_id||','||v_number);
END;

参照表的列类型

使用方式:表名.字段名%type

-- 声明变量
DECLAREv_name tauser.name%type;v_id tauser.loginid%type;v_number NUMBER :=1;--给变量赋值
BEGIN --主体部分SELECT name,loginid INTO v_name,v_id FROM TAUSER WHERE userid = '1';dbms_output.put_line(v_name||','||v_id||','||v_number);
END;

 记录类型

格式:

type 类型名 is record(变量名1,变量名2,
......);
-- 声明变量
DECLARETYPE user_record IS RECORD (v_name tauser.name%TYPE,v_id tauser.loginid%type);u user_record;
BEGIN --主体部分SELECT name,loginid INTO u FROM TAUSER WHERE userid = '1';dbms_output.put_line(u.v_name||','||u.v_id);
END;

参照记录类型

 格式:表名%rowtype

-- 声明变量
DECLAREu tauser%rowtype;
BEGIN --主体部分SELECT * INTO u FROM TAUSER WHERE userid = '1';dbms_output.put_line(u.name||','||u.loginid);
END;

注意:

在PL/SQL中,%ROWTYPE属性定义了一个记录类型,该记录类型的结构与指定的表或视图的整行结构相匹配。因此,如果你使用%ROWTYPE,那么该记录类型将包含表或视图中的所有列。

以下为错误用法:

六、流程控制语句

if语句

语法格式:

IF condition THEN  -- 如果condition为真,则执行这里的代码  [statements]  
[ELSIF condition THEN  -- 如果需要额外的条件检查,可以使用ELSIF(可选)  -- 如果前面的条件都为假,但此条件为真,则执行这里的代码  [elsif_statements]  
...] 
ELSE  -- 如果condition为假,并且提供了ELSE部分,则执行这里的代码  [else_statements]  END IF;

 示例:

DECLARE  v_number NUMBER := 10;  
BEGIN  IF v_number > 0 THEN  DBMS_OUTPUT.PUT_LINE('The number is positive.');  ELSIF v_number = 0 THEN  DBMS_OUTPUT.PUT_LINE('The number is zero.');  ELSE  DBMS_OUTPUT.PUT_LINE('The number is negative.');  END IF;  
END;  

 

循环语句

在PL/SQL中,有几种不同类型的循环可以使用,包括FOR循环、WHILE循环和LOOP(无限循环,通常与EXIT WHEN条件一起使用)。以下是这些循环的使用方式的示例:

FOR 循环

FOR循环通常用于遍历一个集合,如数组或游标。对于数字范围,可以使用FOR ... IN ... LOOP结构。

BEGIN  FOR i IN 1..10 LOOP  DBMS_OUTPUT.PUT_LINE('Value of i: ' || i);  END LOOP;  
END;  

在PL/SQL中,1..10 是一个范围(range)的表示法,它定义了一个从1开始到10结束(包括1和10)的整数序列。这种表示法经常用于FOR循环中,以便迭代一个指定的数字范围 

WHILE 循环

WHILE循环在条件为真时重复执行代码块。

DECLARE  v_counter NUMBER := 1;  
BEGIN  WHILE v_counter <= 10 LOOP  DBMS_OUTPUT.PUT_LINE('Value of v_counter: ' || v_counter);  v_counter := v_counter + 1;  END LOOP;  
END;  

 LOOP 循环(与 EXIT WHEN 一起使用)

LOOP语句创建了一个无限循环,直到遇到EXIT WHEN条件。

DECLARE  v_counter NUMBER := 1;  
BEGIN  LOOP  DBMS_OUTPUT.PUT_LINE('Value of v_counter: ' || v_counter);  v_counter := v_counter + 1;  EXIT WHEN v_counter > 10;  END LOOP;  
END;  
/

在PL/SQL中,EXIT语句用于立即终止当前循环(LOOPFORWHILE循环)的执行,并将控制权转移到循环之后的代码。当与WHEN条件结合使用时(即EXIT WHEN),它允许在特定条件满足时退出循环。 

CURSOR FOR LOOP

当使用游标时,可以使用FOR ... IN ... LOOP结构来遍历游标的结果集。

DECLARE  CURSOR c_employees IS  SELECT employee_id, first_name, last_name FROM employees;  
BEGIN  FOR r_employee IN c_employees LOOP  DBMS_OUTPUT.PUT_LINE('Employee ID: ' || r_employee.employee_id ||   ', Name: ' || r_employee.first_name || ' ' || r_employee.last_name);  END LOOP;  
END;  
/

 在这个示例中,我们定义了一个名为c_employees的游标来从employees表中检索数据,并使用FOR ... IN ... LOOP结构来遍历游标的结果集。在循环体中,我们可以访问游标中每一行的列值。

 七、游标

游标的概念

游标是指向查询结果的指针,指针指向哪条记录,提取的就是哪条记录的数据。

游标的使用流程

  1. 声明游标:定义游标的名称、声明光标变量以及定义光标属性等。
  2. 打开游标:执行查询并将结果存储在游标变量中。
  3. 读取游标:通过FETCH语句从游标中提取数据,并逐行处理。
  4. 关闭游标:使用CLOSE语句关闭游标,释放资源。

游标的属性

游标的属性在PL/SQL中提供了关于游标当前状态和数据检索的详细信息。无论是显式游标还是隐式游标,它们都具有一些共同的属性。以下是游标的属性及其解释:

  1. %FOUND
    • 类型:布尔型(Boolean)
    • 描述:此属性返回一个布尔类型的值,用于指示游标的指针是否指向有效的数据行。如果游标指向的数据不为空(即存在有效数据),则返回TRUE;否则返回FALSE
  2. %NOTFOUND
    • 类型:布尔型(Boolean)
    • 描述:与%FOUND相反,此属性在游标指向的数据为空(即没有有效数据)时返回TRUE。当游标已经遍历完所有数据或尚未开始检索数据时,此属性通常也返回TRUE
  3. %ROWCOUNT
    • 类型:数值型(Numeric)
    • 描述:此属性返回一个数值,表示游标指向的缓冲区(或结果集)中的数据条数。它通常用于跟踪游标已经检索了多少行数据,或者在执行DML操作后确定受影响的行数。
  4. %ISOPEN
    • 类型:布尔型(Boolean)
    • 描述:此属性返回一个布尔类型的值,用于判断当前游标是否打开。如果游标处于打开状态,则返回TRUE;否则返回FALSE。请注意,隐式游标的%ISOPEN属性始终为FALSE,因为隐式游标由Oracle数据库自动管理。

这些属性可以帮助开发人员编写更健壮和可维护的PL/SQL代码,因为它们提供了关于游标状态和数据检索的详细信息。例如,开发人员可以使用%FOUND%NOTFOUND属性来控制循环的迭代,或者使用%ROWCOUNT属性来验证DML操作的结果。

需要注意的是,不同的游标类型(如静态游标、动态游标、隐式游标等)可能在某些方面有所不同,但它们通常都支持上述属性。此外,在使用游标时,还需要注意游标的打开、读取和关闭等操作,以确保正确地处理数据并释放资源。

游标的使用

基本使用

DECLARE  v_name tauser.name%TYPE;v_id tauser.loginid%TYPE;CURSOR tauser_cursor IS SELECT name,loginid FROM TAUSER t ;
BEGIN  OPEN tauser_cursor;FETCH tauser_cursor INTO v_name,v_id;WHILE tauser_cursor%FOUND LOOPdbms_output.put_line(v_name||','||v_id);FETCH tauser_cursor INTO v_name,v_id; --让游标指向下一行end LOOP;
END;  

注意:

错误用法:

 参数化游标

DECLARE  v_name tauser.name%TYPE;v_id tauser.loginid%TYPE;CURSOR tauser_cursor(u_id varchar2) IS SELECT name FROM TAUSER t WHERE userid = u_id ;
BEGIN  OPEN tauser_cursor('1');  -- 传入实际参数 这里传入userid为1FETCH tauser_cursor INTO v_name;WHILE tauser_cursor%FOUND LOOPdbms_output.put_line(v_name);FETCH tauser_cursor INTO v_name;end LOOP;
END;  

游标For循环

DECLARE  CURSOR tauser_cursor IS SELECT name,loginid FROM TAUSER t  ;
BEGIN  FOR u IN tauser_cursor LOOPdbms_output.put_line(u.name);end LOOP;END;  

 带参数的游标For循环

DECLARE  CURSOR tauser_cursor(u_id varchar2) IS SELECT name,loginid FROM TAUSER t WHERE userid=u_id ;
BEGIN  FOR u IN tauser_cursor('1') LOOPdbms_output.put_line(u.name);end LOOP;END;  

 隐式游标

在 PL/SQL 中,隐式游标(Implicit Cursor)是 Oracle 数据库自动为你管理的一种游标,主要用于处理那些不需要显式声明和控制的 SQL 语句。最常见的隐式游标是当你执行 DML(数据操纵语言)语句(如 INSERT、UPDATE、DELETE)和单行 SELECT INTO 语句时,Oracle 会自动为你创建一个隐式游标。

隐式游标的主要特点是:

  1. 自动管理:你不需要显式地声明、打开、获取数据和关闭隐式游标。Oracle 数据库会自动为你完成这些操作。
  2. 属性:隐式游标有一些属性,如 %NOTFOUND%FOUND%ROWCOUNT 和 %ISOPEN。但由于隐式游标是自动管理的,%ISOPEN 总是返回 FALSE,因为它在查询完成后会自动关闭。

示例:

假设你有一个名为 employees 的表,并且你想删除某个员工(假设其 ID 为 1001):

BEGIN  DELETE FROM employees WHERE employee_id = 1001;  IF SQL%NOTFOUND THEN  DBMS_OUTPUT.PUT_LINE('没有找到员工 ID 1001');  ELSE  DBMS_OUTPUT.PUT_LINE('员工 ID 1001 已被删除');  END IF;  
END;  

在上面的示例中,SQL%NOTFOUND 是一个隐式游标的属性,用于检查 DELETE 语句是否影响了任何行。如果没有找到员工 ID 1001,则输出“没有找到员工 ID 1001”;否则输出“员工 ID 1001 已被删除”。注意,这里我们使用了 SQL%NOTFOUND 而不是 employees_cursor%NOTFOUND,因为这是一个隐式游标操作,没有显式声明的游标。

八、异常

在PL/SQL中,异常(Exception)是用于处理运行时错误的一种机制。当PL/SQL块中的代码遇到错误时,它会抛出一个异常。如果没有适当的异常处理代码,程序将终止并返回一个错误消息给用户。但是,通过编写异常处理部分(EXCEPTION section),你可以捕获异常并采取适当的措施,如记录错误信息、回滚事务或提供友好的错误消息给用户。

在PL/SQL中,有两种类型的异常:

  1. 预定义异常:Oracle已经为常见的错误情况定义了异常。例如,NO_DATA_FOUND(当SELECT INTO语句没有返回任何行时)和TOO_MANY_ROWS(当SELECT INTO语句返回多行时)。预定义异常不需要显式声明,但你可以在EXCEPTION部分中捕获它们。

  2. 用户定义异常:你可以使用DECLARE部分中的EXCEPTION关键字来声明你自己的异常。这允许你定义和处理特定的错误情况。

示例:使用预定义异常

DECLARE  v_employee_name VARCHAR2(50);  
BEGIN  SELECT first_name INTO v_employee_name  FROM employees  WHERE employee_id = 1001;  -- 如果这里employee_id为1001的员工不存在,将会抛出NO_DATA_FOUND异常  DBMS_OUTPUT.PUT_LINE('Employee name: ' || v_employee_name);  
EXCEPTION  WHEN NO_DATA_FOUND THEN  DBMS_OUTPUT.PUT_LINE('No employee found with ID 1001');  WHEN OTHERS THEN  DBMS_OUTPUT.PUT_LINE('An error occurred: ' || SQLERRM);  
END;  

示例:使用用户定义异常

DECLARE  v_employee_salary NUMBER;  salary_too_high EXCEPTION; -- 声明用户定义异常  
BEGIN  SELECT salary INTO v_employee_salary  FROM employees  WHERE employee_id = 1001;  IF v_employee_salary > 100000 THEN  RAISE salary_too_high; -- 触发用户定义异常  END IF;  -- 其他代码...  
EXCEPTION  WHEN salary_too_high THEN  DBMS_OUTPUT.PUT_LINE('Salary is too high for this employee');  WHEN OTHERS THEN  DBMS_OUTPUT.PUT_LINE('An error occurred: ' || SQLERRM);  
END;  

九、函数和过程

函数和过程介绍

1.Oracle提供可以把PL/SQL程序存储在数据库中,并可以再任何地方来运行它,这样就叫存储过程或函数。

2.过程和函数统称PL/SQL子程序,它们是被命名的PL/SQL块,均存储在数据库中,并通过输入、输出参数或者输入/输出参数预期调用者交换信息。

3.过程和函数的唯一区别是函数总向调用者返回数据(函数必须有返回值),而过程则不返回数据(过程没有返回值)。

函数的创建

创建语法:

CREATE OR REPLACE FUNCTION function_name (  parameter1 datatype [DEFAULT value],  parameter2 datatype [DEFAULT value],  ...  
) RETURN return_datatype  
IS  -- 声明变量  variable_declaration;  
BEGIN  -- 函数体  -- 执行逻辑,返回结果  RETURN result;  
EXCEPTION  -- 异常处理  WHEN exception_name THEN  -- 处理异常的代码  ...  
END;  

其中:

  • function_name:函数的名称。
  • parameter1, parameter2, ...:函数的参数列表。每个参数都有一个名称和数据类型,可以有一个默认值。
  • return_datatype:函数返回值的数据类型。
  • variable_declaration:在 IS 和 BEGIN 之间,你可以声明函数体内将使用的变量。
  • RETURN result;:函数体中的这一行表示函数将返回的值。
  • EXCEPTION 部分是可选的,用于处理在函数执行过程中可能发生的异常。

函数的参数类型

在 PL/SQL 中,函数(Function)允许你封装一段逻辑代码,并可以传递参数和返回结果。PL/SQL 是 Oracle 数据库中的过程化 SQL 语言扩展,它允许你在数据库中创建存储过程、函数、触发器等。

函数的参数可以有不同的模式(Mode)和数据类型。在 PL/SQL 中,函数的参数主要有以下几种模式:

  1. IN 模式:这是默认的参数模式,用于向函数传递值。在函数体内,这些参数是只读的,不能被修改。
  2. OUT 模式:这种参数用于从函数返回多个值。在调用函数之前,OUT 参数不需要被赋值。在函数体内,OUT 参数可以被赋予新的值,并在函数执行完毕后返回给调用者。
  3. IN OUT 模式:这种参数既可以接收传入的值,也可以返回修改后的值。

下面是一个简单的 PL/SQL 函数示例,该函数接受一个 IN 模式的 NUMBER 类型参数,并返回它的平方:

CREATE OR REPLACE FUNCTION square_number(p_number IN NUMBER)  
RETURN NUMBER IS  v_result NUMBER;  
BEGIN  v_result := p_number * p_number;  RETURN v_result;  
END square_number;  

注意:无论是返回值类型还是参数类型,都只需要写数据类型,不需要写括号。

例如:varchar2,number是正确的,varchar2(50),number(7,2)这种写法是错误的。

函数的调用

一旦你创建了函数,你就可以在 SQL 语句或 PL/SQL 块中调用它。

示例:

SELECT square_number(5) FROM DUAL;

过程的创建

在PL/SQL中,存储过程(Stored Procedure)是存储在数据库中的一组为了完成特定功能的SQL语句集。存储过程可以被视为一个命名的PL/SQL块,它可以从应用程序中被调用,并且可以接受参数和返回状态值。

以下是PL/SQL中存储过程的基本创建语法:

CREATE OR REPLACE PROCEDURE procedure_name   [ (parameter_name [ IN | OUT | IN OUT ] data_type [, ...] ) ]   
IS   [declaration_section]   
BEGIN   executable_section   
[EXCEPTION   exception_handling_section]   
END [procedure_name];
  • CREATE OR REPLACE PROCEDURE: 用于创建或替换一个已存在的存储过程。
  • procedure_name: 存储过程的名称。
  • parameter_name: 参数的名称。
  • IN | OUT | IN OUT: 参数的模式。IN是默认值,表示参数是输入参数;OUT表示参数是输出参数,用于从存储过程返回数据;IN OUT表示参数既可以输入也可以输出。
  • data_type: 参数的数据类型。
  • declaration_section: 可选部分,用于声明变量、常量、游标等。
  • executable_section: 存储过程的主体部分,包含要执行的PL/SQL语句和逻辑。
  • exception_handling_section: 可选部分,用于处理在executable_section中可能发生的异常。

下面是一个简单的存储过程示例,它接受一个输入参数并插入到一张表中:

CREATE OR REPLACE PROCEDURE insert_into_employees (p_emp_id IN NUMBER, p_emp_name IN VARCHAR2)   
IS   
BEGIN   INSERT INTO employees (emp_id, emp_name) VALUES (p_emp_id, p_emp_name);   COMMIT;   
EXCEPTION   WHEN OTHERS THEN   ROLLBACK;   RAISE_APPLICATION_ERROR(-20001, 'An error occurred: ' || SQLERRM);   
END insert_into_employees;  

在这个示例中,存储过程insert_into_employees接受两个输入参数p_emp_idp_emp_name,并将它们插入到employees表中。如果在插入过程中发生任何错误,它会回滚事务并抛出一个自定义的错误。

过程的调用

要调用存储过程,你可以使用EXECUTE语句或者匿名PL/SQL块:

EXECUTE insert_into_employees(100, 'John Doe');
BEGIN  insert_into_employees(100, 'John Doe');  
END;  

函数和存储过程示例

从Oracle自定义函数和存储过程案例学习PL/SQL的使用-CSDN博客

十、包

在 PL/SQL 中,包(Package)是一个数据库对象,它允许你将相关的 PL/SQL 类型、变量、常量、子程序、游标等组合成一个逻辑单元。包的主要目的是封装和组织代码,提高代码的可读性、可维护性和重用性。

一个包由两部分组成:包头(Package Specification)和包体(Package Body)。

包头(Package Specification)

  • 定义了包中公共类型、变量、常量、子程序、游标等的接口。
  • 其他数据库对象或用户只能看到和引用包头中定义的这些公共元素。
  • 包头中的声明决定了哪些元素是公共的(可以在包外部访问),哪些是私有的(只能在包内部访问)。

包体(Package Body)

  • 包含了包头中声明的公共元素和私有元素的实现。
  • 私有元素在包体外部是不可见的,但它们可以在包体内的任何子程序中引用。
  • 包体可以包含类型、变量、常量、子程序、游标等的定义和实现。

使用包的好处

  1. 封装性:包可以将相关的代码和数据封装在一起,隐藏实现细节,只暴露必要的接口。
  2. 重用性:通过封装公共的类型、子程序等,包提高了代码的重用性。
  3. 性能优化:由于包中的代码和数据在内存中只存储一次,因此可以提高访问速度和执行效率。
  4. 易于维护:通过组织和封装代码,包使得代码更易于阅读、理解和维护。
  5. 安全性:通过控制对包中元素的访问权限,可以提高数据的安全性。

示例

以下是一个简单的 PL/SQL 包示例:

包头(my_package_spec.pks):

CREATE OR REPLACE PACKAGE my_package AS  -- 公共类型  TYPE my_type IS TABLE OF VARCHAR2(50);  -- 公共常量  CONSTANT my_constant NUMBER := 100;  -- 公共子程序  FUNCTION get_data RETURN my_type;  PROCEDURE process_data(p_data IN my_type);  
END my_package;  

包体(my_package_body.pkb)

CREATE OR REPLACE PACKAGE BODY my_package AS  -- 私有变量  PRIVATE my_private_var NUMBER := 0;  -- 公共子程序实现  FUNCTION get_data RETURN my_type IS  v_data my_type := my_type('Data1', 'Data2', 'Data3');  BEGIN  RETURN v_data;  END get_data;  PROCEDURE process_data(p_data IN my_type) IS  BEGIN  -- 处理数据的逻辑  FOR i IN 1..p_data.COUNT LOOP  DBMS_OUTPUT.PUT_LINE(p_data(i));  END LOOP;  END process_data;  
END my_package;  

 在这个示例中,我们创建了一个名为 my_package 的包,它包含一个公共类型 my_type、一个公共常量 my_constant、一个公共函数 get_data 和一个公共过程 process_data。包体还包含一个私有变量 my_private_var

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

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

相关文章

Hallo:分级音频驱动视觉合成肖像动画

团队&#xff1a;百度&#xff08;王井东大佬&#xff09;&#xff0c;复旦&#xff0c;瑞士ETH&#xff0c;南大 文章目录 概要介绍相关工作整体架构流程技术名词解释层次音频驱动的视觉合成训练和推理训练实验设置讨论社会风险和缓解措施小结 概要 肖像图像动画领域&#x…

如何修改PDF文档的作者名称?

要修改一个 PDF 文档的作者名称&#xff0c;你可以按照以下步骤进行操作&#xff1a; 1. **使用 Adobe Acrobat**&#xff08;如果有&#xff09;&#xff1a; - Adobe Acrobat 是一个功能强大的 PDF 编辑工具&#xff0c;支持修改文档属性信息&#xff0c;包括作者名称。打开…

一个用于自动复制文本的小工具:Auto_Copy

自动复制工具 这是一个在 Windows 上用于自动复制选中文本到剪贴板的小工具。该工具还允许通过右键单击粘贴剪贴板内容。 灵感来源: 在使用Mobaxterm时,我注意到其软件中具备选中即自动复制和右键直接粘贴的功能。但是,这种选中自动复制的功能仅在软件内部有效。由于这一功能…

什么是无头浏览器?

简而言之&#xff0c;无头浏览器是没有图形用户界面 &#xff08;GUI&#xff09; 的 Web 浏览器。GUI 包括用户与之交互的数字元素&#xff0c;例如按钮、图标和窗口。但是&#xff0c;关于无头浏览器&#xff0c;您需要了解的还有很多。 在本文中&#xff0c;您将了解什么是…

Go语言环境安装 第一个Go程序

Go下载地址 哪个能用用哪个。 https://go.dev/ https://golang.google.cn/&#xff08;Golang官网的官方镜像&#xff09; Windows 使用.msi安装包安装 下载msi文件 安装 双击运行go1.22.4.windows-amd64.msi Next 勾选I accept the terms in the License Agreement&…

Webpack: 持久化缓存大幅提升构建性能

概述 缓存是一种应用非常广泛性能优化技术&#xff0c;在计算机领域几乎无处不在&#xff0c;例如&#xff1a;操作系统层面 CPU 高速缓存、磁盘缓存&#xff0c;网路世界中的 DNS 缓存、HTTP 缓存&#xff0c;以及业务应用中的数据库缓存、分布式缓存等等。 那自然而然的&am…

路径规划 | 基于蜣螂优化算法的栅格地图机器人路径规划(Matlab)

目录 效果一览基本介绍程序设计参考文献 效果一览 基本介绍 路径规划 | 基于蜣螂优化算法的栅格地图机器人路径规划&#xff08;Matlab&#xff09; 1.利用蜣螂算法DBO优化栅格地图机器人路径规划&#xff0c;效果如图所示&#xff0c;包括迭代曲线图、栅格地图等等&#xff5e…

VScode配置

1.设置鼠标悬停提示 1.1 问题描述 打开vscode&#xff0c;按住ctrl鼠标左键不能跳转定义&#xff08;右键没有go to definition&#xff09; 1.2 解决办法 打开设置界面&#xff1a;文件->首选项->设置在搜索框中搜索intelli Sense Engine &#xff08;需要先安装C/C…

【Python】已解决:ModuleNotFoundError: No module named ‘sklearn‘

文章目录 一、分析问题背景二、可能出错的原因三、错误代码示例四、正确代码示例五、注意事项 已解决&#xff1a;ModuleNotFoundError: No module named ‘sklearn‘ 一、分析问题背景 在进行机器学习项目时&#xff0c;Scikit-Learn&#xff08;简称sklearn&#xff09;是一…

Linux多进程和多线程(二)-进程间通信-管道用法

进程间通信 关于多进程的通信管道无名管道(匿名管道)创建无名管道示例:创建子进程,父进程通过管道向子进程发送消息无名管道(匿名管道) 的特点 有名管道(命名管道) 创建有名管道需要调⽤ mkfifo() 函数示例:创建两个没有关联关系的进程,通过有名管道通信 注意: 缺点优点 关于判…

Linux多进程和多线程(一)-进程的概念和创建

进程 进程的概念进程的特点如下进程和程序的区别LINUX进程管理 getpid()getppid() 进程的地址空间虚拟地址和物理地址进程状态管理进程相关命令 ps toppstreekill 进程的创建 并发和并行fork() 父子进程执行不同的任务创建多个进程 进程的退出 exit()和_exit() exit()函数让当…

七日世界Once Human跳ping、延迟高、丢包怎么办?

七日世界是一款开放世界为轴点的生存射击游戏&#xff0c;玩家将进入一个荒诞、荒芜的末日世界&#xff0c;在这里与好友一起对抗可怖的怪物和神秘物质星尘的入侵&#xff0c;给这个星球留下最后的希望&#xff0c;共筑一片安全的领地。不过有部分玩家在游玩七日世界的时候&…

昇思MindSpore学习笔记7--函数式自动微分

摘要&#xff1a; 介绍了昇思MindSpore神经网络训练反向传播算法中函数式自动微分的使用方法和步骤。包括构造计算函数和神经网络、grad获得微分函数&#xff0c;以及如何处理停止渐变、获取辅助数据等内容。 一、概念要点 神经网络训练主要使用反向传播算法&#xff1a; 准备…

从AICore到TensorCore:华为910B与NVIDIA A100全面分析

华为NPU 910B与NVIDIA GPU A100性能对比&#xff0c;从AICore到TensorCore&#xff0c;展现各自计算核心优势。 AI 2.0浪潮汹涌而来&#xff0c;若仍将其与区块链等量齐观&#xff0c;视作炒作泡沫&#xff0c;则将错失新时代的巨大机遇。现在&#xff0c;就是把握AI时代的关键…

RAG 基本流程及处理技巧 with LangChain

LLM 主要存在两个问题&#xff1a;幻想和缺乏领域知识。领域知识缺乏的原因是因为训练 LLM 本身的知识更新慢&#xff0c;对特定领域的知识也没有太细致的输入。 RAG 主要是解决 LLM 缺乏领域知识的问题。底层的逻辑是&#xff1a;把 LLM 作为逻辑推理引擎&#xff0c;而不是信…

机器学习--概念理解

知识点 一、机器学习概述 人工智能 机器学习 深度学习 学习的范围&#xff1a;模式识别、数据挖掘、统计学习、计算机视觉、语音识别、自然语言处理 可以解决的问题&#xff1a;给定数据的预测问题 二、机器学习的类型 监督学习 分类 回归 无监督学习 聚类 降维 强化…

恢复的实现技术-日志和数据转储

一、引言 在系统正常运行的情况下&#xff0c;事务处理的恢复机制应采取某些技术措施为恢复做好相应的准备&#xff0c;保证在系统发生故障后&#xff0c;能将数据库从一个不一致的错误状态恢复到一个一致性状态 恢复技术主要包括 生成一个数据库日志&#xff0c;来记录系统中…

Unity制作一个简单抽卡系统(简单好抄)

业务流程&#xff1a;点击抽卡——>播放动画——>显示抽卡面板——>将随机结果添加到面板中——>关闭面板 1.准备素材并导入Unity中&#xff08;包含2个抽卡动画&#xff0c;抽卡结果的图片&#xff0c;一个背景图片&#xff0c;一个你的展示图片&#xff09; 2.给…

创建一个vue3+vite+ts项目

目录 创建项目 ​编辑 下载jsx 插件 在根目录在新建.env vue.config.js tsconfig.json tsconfig.node.json 下载ui组件库和路由&#xff08;组件库根据自己的项目需要选择&#xff09; 在根目录下新建views/index.tsx 在根目录下新建router/index.ts 修改App.vue 创建…

机器学习原理之 -- 朴素贝叶斯分类器:由来及原理详解

朴素贝叶斯&#xff08;Naive Bayes&#xff09;分类器是一类基于贝叶斯定理&#xff08;Bayes Theorem&#xff09;的简单而有效的概率分类算法。由于其假设特征之间的条件独立性&#xff0c;因此被称为“朴素”贝叶斯分类器。尽管这种独立性假设在现实中很少完全成立&#xf…