PL/SQL基础(2):单元

2023-05-16

本篇是 Oracle基础小结 系列之一。


PL/SQL程序单元包括:PL/SQL匿名块、PL/SQL函数、PL/SQL存储过程、PL/SQL包、PL/SQL触发器等。这里就用过的几个做简单记录,另外虽然PL/SQL异常处理不是程序单元,但也是其中重要的组成部分,也放在这里一并阐述。因此这部分包括:

1、PL/SQL匿名块

2、PL/SQL函数

3、PL/SQL存储过程

4、PL/SQL包

5、PL/SQL触发器

6、PL/SQL异常处理

 

PL/SQL匿名块

PL/SQl匿名块即是PL/SQL单元的基础,其它程序单元均是匿名块增加单元头信息构成相应功能单元。注意PL/SQL里的变量需要在BEGIN前先声明。一个PL/SQL匿名块(Wiki)如下:

<<label>>  -- this isoptional

declare

-- this section is optional

  number1 number(2);

  number2 number1%type    :=17;            -- value default

  text1   varchar2(12) :='Hello world';

  text2   date         := SYSDATE;       -- current date and time

begin

-- this section is mandatory, must contain at least oneexecutable statement

  SELECT street_number

    INTO number1

    FROM address

    WHERE name = 'INU';

exception

-- this section is optional

   WHEN OTHERS THEN

    DBMS_OUTPUT.PUT_LINE('Error Code is '||to_char(sqlcode )  );

    DBMS_OUTPUT.PUT_LINE('Error Message is '|| sqlerrm   );

end;

引用:

https://en.wikipedia.org/wiki/PL/SQL#PL.2FSQL_anonymous_block

 

PL/SQL函数

         PL/SQL函数同其它语言函数一样,参数有输入(IN)输出(OUT)引用(IN OUT),并且有返回值(RETURN)。函数的参数类型不带长度信息,这点与声明部分不同。

格式:

CREATE [OR REPLACE] FUNCTION function_name

[(parameter_name [IN | OUT | IN OUT] type[, ...])]

RETURN return_datatype

{IS | AS}

BEGIN

  < function_body >

END [function_name];

示例:

1. create or replace function func  (  

2.         -- 入参、出参列表, 逗号分隔。  

3.         uid in varchar2,                          -- 不能带长度信息  

4.         startDate in date,                        -- 第二个输入参数  

5.         defaultVar in varchar2 default "",        -- 默认参数,如果不传,要注意参数的顺序  

6.         isok out number,                          -- 输出参数  

7.         result out varchar2                       -- 第二个输出参数  

8. )  

9. return number      -- 定义返回类型  

10.as  

11.-- 变量声明,每个声明用分号结束。可以在声明的同时初始化  

12.var1 varchar2(11);  

13.var2 number(2) := 123;  

14.  

15.begin  

16.        -- 字符串拼接用 ||  

17.        dbms_output.put_line('isok:' || 'abc');  

18.         

19.  

20.        return ret_val;  

21.end;  

引用:

http://www.tutorialspoint.com/plsql/plsql_functions.htm

http://wen866595.iteye.com/blog/1733887

 

PL/SQL存储过程

         PL/SQL的存储过程在结构上与函数有些类似,但是不带返回值。结构如下:

CREATE [OR REPLACE] PROCEDUREprocedure_name

[(parameter_name [IN | OUT | IN OUT] type[, ...])]

{IS | AS}

BEGIN

 < procedure_body >

END procedure_name;

         示例如下:

1. create or replace procedure sp_name (  

2.         -- 入参、出参列表, 逗号分隔。  

3.         uid in varchar2,                          -- 不能带长度信息  

4.         startDate in date,                        -- 第二个输入参数  

5.         defaultVar in varchar2 default "",        -- 默认参数,如果不传,要注意参数的顺序  

6.         isok out number,                          -- 输出参数  

7.         result out varchar2                       -- 第二个输出参数  

8. )  

9. as  

10.-- 变量声明,每个声明用分号结束。可以在声明的同时初始化  

11.var1 varchar2(11);  

12.var2 number(2) := 123;  

13.  

14.begin  

15.        -- 字符串拼接用 ||  

16.        dbms_output.put_line('isok:' || 'abc');  

17.         

18.        -- 调用其他存储过程  

19.        sub_sp_name(param1, prarm2, outParam1, outParam2);  

20.  

21.end;        -- 存储过程结束  

22./

 

引用:

http://www.tutorialspoint.com/plsql/plsql_procedures.htm

http://wen866595.iteye.com/blog/1733887

 

PL/SQL包

         PL/SQL包是包含类型、变量和子程序等的模式对象,类似于面向对象中类的概念。PL/SQL包包括包的声明(Package specification)和包体或定义(Package body or definition)两部分。包的声明例子如下:

CREATE PACKAGE cust_sal AS

  PROCEDURE find_sal(c_id customers.id%type);

END cust_sal;

/

包体的例子如下:

CREATE OR REPLACE PACKAGE BODY cust_sal AS

  PROCEDURE find_sal(c_id customers.id%TYPE) IS

  c_sal customers.salary%TYPE;

  BEGIN

     SELECT salary INTO c_sal

     FROM customers

     WHERE id = c_id;

     dbms_output.put_line('Salary: '|| c_sal);

  END find_sal;

END cust_sal;

/

包创建后,访问包中元素(变量、函数、存储过程等),使用package_name.element_name;使用上面包的程序如下:

DECLARE

   code customers.id%type := &cc_id;

BEGIN

   cust_sal.find_sal(code);

END;

/

引用:

http://www.tutorialspoint.com/plsql/plsql_packages.htm

 

PL/SQL触发器

         触发器存储了在某些事件发生时触发的程序。通常用于数据库操作(DELETE, INSERT, or UPDATE)、数据库定义(CREATE,ALTER, or DROP)和数据库操纵(SERVERERROR, LOGON, LOGOFF, STARTUP, or SHUTDOWN)。它经常用于实现Oracle数据库的自增等。创建触发器的结构如下:

CREATE [OR REPLACE ] TRIGGER trigger_name

{BEFORE | AFTER | INSTEAD OF }

{INSERT [OR] | UPDATE [OR] | DELETE}

[OF col_name]

ON table_name

[REFERENCING OLD AS o NEW AS n]

[FOR EACH ROW]

WHEN (condition) 

DECLARE

  Declaration-statements

BEGIN

  Executable-statements

EXCEPTION

  Exception-handling-statements

END;

引用:

http://www.tutorialspoint.com/plsql/plsql_triggers.htm

 

PL/SQL异常处理

         PL/SQL异常处理(EXCEPTION)用于捕捉抛出和处理异常。异常信息有两种:系统预定义和用户自定义。EXCEPTION写在BEGIN END块之间。在异常处理时,通常可以写ROLLBACK;语句来回滚。EXCEPTION的语法结构如下:

DECLARE

  <declarations section>

BEGIN

  <executable command(s)>

EXCEPTION

  <exception handling goes here >

  WHEN exception1 THEN -- exception1可以是系统预定义或用户自定义

      exception1-handling-statements

  WHEN exception2  THEN

     exception2-handling-statements

  WHEN exception3 THEN

     exception3-handling-statements

  ........

  WHEN others THEN

     exception3-handling-statements

END;

在程序执行中还可以使用RAISE主动报异常,尤其是用户自定义异常,其语法结构如下:

DECLARE

  exception_name EXCEPTION;

BEGIN

   IFcondition THEN

     RAISE exception_name;

  END IF;

EXCEPTION

  WHEN exception_name THEN

  statement;

END;

         一个EXCEPTION例子如下,这里既包含可系统预定义异常也包括了用户自定义异常,同时使用了RAISE和raise_application_error报异常。raise_application_error的好处在于可以把生涩的系统异常提示,写成软件相关的用户可理解的异常提示。

CREATE OR REPLACE PROCEDURE add_new_order

  (order_id_in IN NUMBER, sales_in IN NUMBER)

IS

  no_sales EXCEPTION;        -- 自定义异常类型变量

BEGIN

   IFsales_in = 0 THEN

     RAISE no_sales;            -- 报异常

  ELSE

     INSERT INTO orders (order_id, total_sales )

     VALUES ( order_id_in, sales_in );

  END IF;

EXCEPTION

  WHEN DUP_VAL_ON_INDEX THEN

     raise_application_error (-20001,'You have tried to insert a duplicateorder_id.');     -- 将系统预定义异常以一种用户可理解的提示报出来

  WHEN no_sales THEN

     raise_application_error (-20001,'You must have sales in order to submitthe order.');     -- 将用户自定义异常以一种用户可理解的提示报出来

  WHEN OTHERS THEN

     raise_application_error (-20002,'An error has occurred inserting anorder.');  -- 以通用消息报其他异常

END;

/

附Oracle预定义的异常:

Exception

Oracle Error

SQLCODE

Description

ACCESS_INTO_NULL

06530

-6530

It is raised when a null object is automatically assigned a value.

CASE_NOT_FOUND

06592

-6592

It is raised when none of the choices in the WHEN clauses of a CASE statement is selected, and there is no ELSE clause.

COLLECTION_IS_NULL

06531

-6531

It is raised when a program attempts to apply collection methods other than EXISTS to an uninitialized nested table or varray, or the program attempts to assign values to the elements of an uninitialized nested table or varray.

DUP_VAL_ON_INDEX

00001

-1

It is raised when duplicate values are attempted to be stored in a column with unique index.

INVALID_CURSOR

01001

-1001

It is raised when attempts are made to make a cursor operation that is not allowed, such as closing an unopened cursor.

INVALID_NUMBER

01722

-1722

It is raised when the conversion of a character string into a number fails because the string does not represent a valid number.

LOGIN_DENIED

01017

-1017

It is raised when s program attempts to log on to the database with an invalid username or password.

NO_DATA_FOUND

01403

+100

It is raised when a SELECT INTO statement returns no rows.

NOT_LOGGED_ON

01012

-1012

It is raised when a database call is issued without being connected to the database.

PROGRAM_ERROR

06501

-6501

It is raised when PL/SQL has an internal problem.

ROWTYPE_MISMATCH

06504

-6504

It is raised when a cursor fetches value in a variable having incompatible data type.

SELF_IS_NULL

30625

-30625

It is raised when a member method is invoked, but the instance of the object type was not initialized.

STORAGE_ERROR

06500

-6500

It is raised when PL/SQL ran out of memory or memory was corrupted.

TOO_MANY_ROWS

01422

-1422

It is raised when s SELECT INTO statement returns more than one row.

VALUE_ERROR

06502

-6502

It is raised when an arithmetic, conversion, truncation, or size-constraint error occurs.

ZERO_DIVIDE

01476

1476

It is raised when an attempt is made to divide a number by zero.

 

引用:

https://www.techonthenet.com/oracle/exceptions/when_others.php

http://www.tutorialspoint.com/plsql/plsql_exceptions.htm

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

PL/SQL基础(2):单元 的相关文章

  • SQL:链接连接效率

    我的 WordPress 插件中有一个查询 如下所示 SELECT users U meta value AS first name M meta value AS last name FROM nwp users AS users LEF
  • Oracle 中四舍五入到特定有效数字位数

    oracle 是否有舍入函数可以四舍五入到特定数量的有效数字 例如 将 1278 舍入到 1300 四舍五入到两位有效数字 Try ROUND x d FLOOR LOG 10 x 1 where d是有效位数 x是要四舍五入的值 Exam
  • 在 PostgreSQL 函数中声明并返回自定义类型

    我找到了这篇文章 http wiki postgresql org wiki Return more than one row of data from PL pgSQL functions http wiki postgresql org
  • 我的代码中出现内存不足异常

    作为 Oracle 数据库压力测试的一部分 我正在长时间运行代码并使用 java 版本 1 4 2 简而言之 我正在做的是 while true Allocating some memory as a blob byte data new
  • 获取前 5 个频繁值及其总数 Linq-to-Sql

    我正在使用这个 Linq to sql 来获取最多出现的记录 List
  • Bigquery - json_array 来自字段的额外多个元素

    我的表有一个 JSON 字段 如下所示 每个条目中可以有任意数量的评论 entry 1234 comment 6789 seconds 1614864327 nanoseconds 606000000 message hello world
  • 如何使用 JDBC 进行扩展插入而不构建字符串?

    我有一个应用程序可以解析日志文件并将大量数据插入数据库 它是用 Java 编写的 并通过 JDBC 与 MySQL 数据库通信 我尝试了不同的插入数据的方法 以找到适合我的特定用例的最快方法 目前看来表现最好的方法是发出扩展插入 例如 具有
  • 创建从最后一个索引增加的列[重复]

    这个问题在这里已经有答案了 我需要为 InvoiceID 生成一列 我想像这样保留本专栏的格式 INV0000001 INV0000002 INV0000010 INV0000011 and so on 正如您所看到的 该列随着最后一个索引
  • 如何将具有结构的行从一个表插入到另一个表?

    SQL Server 中将具有结构的行从一个表插入到另一个表的查询是什么 有几种方法 选择进入 SELECT field1 field2 INTO Table1 FROM Table2 插入 INSERT INTO Table1 field
  • 如何使用 Postgres 轻松从文本字段中获取缩写

    我正在使用 Postgres 版本 9 4 并且我有一个full name表中的字段 在某些情况下 我想在表中输入姓名的首字母而不是全名 就像是 Name Initials Joe Blow J B Phil Smith P S The f
  • 查询具有相同ID的同一列中具有不同值的SQL表

    我有一个 SQL Server 2012 表ID First Name and Last name The ID每个人都是唯一的 但由于历史提要中的错误 不同的人被分配了相同的 ID ID FirstName LastName 1 ABC
  • 如何从 Oracle 中的日期中减去小时数,以便它也影响当天

    我正在尝试从 Oracle 中减去日期 这样它甚至也会影响这一天 例如 如果 时间戳是 01 June 2015 00 小时 如果我减去 2 小时 我希望能够转到 31 May 2014 22 小时 I tried to char sysd
  • 找出 2 个日期之间的月数

    select age 2012 11 30 00 00 00 timestamp 2012 10 31 00 00 00 timestamp age 2012 12 31 00 00 00 timestamp 2012 10 31 00 0
  • mysql错误1064

    我正在尝试使用以下代码创建一个表 CREATE TABLE IF NOT EXISTS entries id int 10 NOT NULL auto increment atom id varchar 512 NOT NULL title
  • 在数据库中存储非常大的文件

    在数据库中存储大文件 大约 100 GB 是个好主意吗 目前我们考虑使用NBT格式或使用mysql postgresql数据库将数据保存在文件夹中 数据库旨在对大量小数据进行排序 过滤和执行计算 如果您只想拥有一个文件系统 例如 对聚合按上
  • SQL——排序数据

    因此 我的学校老师要求我从现有数据库中整理一些数据 这很容易手动完成 但如果记录超过 100 条 则时间太长 他是这样问我的 有单独的桌子 其中一个称为 联系人 有 2 列 ID 姓名 第二个称为电子邮件 和第三个 CONT EMAIL 他
  • 如何查找给定日期范围内的列总和,其中表只有开始日期和结束日期

    我有一个像这样的 postgresql 表 userDistributions user id start date end date project id distribution 我需要编写一个查询 其中给定的日期范围和用户 ID 的输
  • SQL-计算数字列值的增加百分比

    我想根据 SQL 数据库中获得的值计算一些趋势 我特别感兴趣的是获取一列中值的增加百分比 如果值减少 则该值应该为负数 有人可以建议我该怎么做吗 我无法使用存储过程 Thanks 我的表有以下列 日期 数字 月份 数字 订单 数字 价格 实
  • Oracle 中的重复行

    如何防止在选择查询中选择重复的行 我有一个包含以下字段的表 name type user1 user2 user3 date 我的查询要求我仅在用户在前端输入的时间为特定用户选择数据 假设用户输入 1 那么选择查询应仅检索 user1 的数
  • 如何从 VB.NET 中的存储过程获取返回值

    我在 SQL Server 中有一个存储过程用于生成事务号 任何人都可以帮助我如何从 VB NET 调用存储过程以及如何获取从过程返回到前端的值 问候 乔治 我想你想要这样的东西 Public Sub Foo Using sql As Ne

随机推荐

  • JSON是什么

    提起 JSON xff0c 作为如今最受欢迎的数据交换格式 xff0c 可以说是无人不知 无人不晓了 JSON 全称 JavaScript Object Notation xff08 JS 对象简谱 xff09 xff0c 自诞生之初的小目
  • 【C++】数组定义引发Stack overflow错误(运行时是报段错误)

    C 43 43 xff08 实际是C的语法 xff09 定义数组时出错 xff0c 代码如下 xff1a float t1 9830400 调试时触发Stack overflow错误 xff08 可执行文件运行时 xff0c 是报段错误 x
  • 【C/C++】数组初始化

    数组定义不初始化会被随机赋值 因此如果数组的所有元素在下面没有逐一赋值 xff0c 但是又会使用到的话 xff0c 最后不要只定义而不初始化 会带来问题 数组初始化的几种形式 可以直接用 xff1a a 10 61 xff0c 就可以让a
  • 【C++】指针数组与数组指针

    指针数组 指针数组可以说成是 指针的数组 xff0c 首先这个变量是一个数组 xff0c 其次 xff0c 指针 修饰这个数组 xff0c 意思是说这个数组的所有元素都是指针类型 xff0c 在32位系统中 xff0c 指针占四个字节 定义
  • 【旋转框目标检测】2201_The KFIoU Loss For Rotated Object Detection

    paper with code paper code Jittor Code https github com Jittor JDet PyTorch Code https github com open mmlab mmrotate Te
  • CUDA编译报错unsupported GNU version! gcc versions later than 10 are not supported!

    问题 xff1a python编译用于cuda的so文件中 xff0c 使用编译 cu文件出错 xff1a error unsupported GNU version gcc versions later than 10 are not s
  • RuntimeError: CUDA error: no kernel image is available for execution on the device

    问题 xff1a 代码换机器执行时 xff0c 使用包含自行编译的cuda算子库so时出错 xff1a RuntimeError CUDA error no kernel image is available for execution o
  • Ubuntu非LTS版本安装nvidia-docker出错:Unsupported distribution!

    问题 xff1a 按照Nvidia官方流程 xff0c 在Ubuntu22 10安装nvidia docker在执行以下命令时 distribution 61 etc os release echo ID VERSION ID amp am
  • 测试torch方法是否支持半精度

    并不是所有的torch方法都支持半精度计算 测试半精度计算需要在cuda上 xff0c cpu不支持半精度 因此首先需要创建半精度变量 xff0c 并放到cuda设备上 部分方法在低版本不支持 xff0c 在高版本支持半精度计算 xff0c
  • yolov5关闭wandb

    yolov5训练过程中wandb总是提示登入账号 xff0c 不登入还不能继续训练 xff0c 想要关闭wandb xff0c 直接不使用即可 在 yolov5 utils loggers wandb wandb utils py中 imp
  • 目标检测 YOLOv5的loss权重,以及与图像大小的关系

    1 目标检测 YOLOv5的loss权重 YOLOv5中有三个损失分别是 box obj cls 在超参数配置文件hyp yaml中可以设置基础值 xff0c 例如 box 0 05 cls 0 5 obj 1 训练使用时 xff0c 在t
  • 手写一个JSON反序列化程序

    上一篇文章 JSON是什么 给大家介绍了JSON的标准规范 xff0c 今天就自己动手写一个JSON的反序列化程序 xff0c 并命名它为 zjson 0 开始之前 本篇文章的目的是学习实践 xff0c 所以我们选择相对简单的Python实
  • yolov5源码解析--输出

    本文章基于yolov5 6 2版本 主要讲解的是yolov5是怎么在最终的特征图上得出物体边框 置信度 物体分类的 一 总体框架 首先贴出总体框架 xff0c 直接就拿官方文档的图了 xff0c 本文就是接着右侧的那三层输出开始讨论 Bac
  • yolov5源码解析--损失计算与anchor

    本文章基于yolov5 6 2版本 主要讲解的是yolov5在训练过程中是怎么由推理结果和标签来进行损失计算的 损失函数往往可以作为调优的一个切入点 xff0c 所以我们首先要了解它 一 代码入口 损失函数的调用点如下 xff0c 在tra
  • 多任务学习中各loss权重应该如何设计呢?

    来源 xff1a 22 封私信 80 条消息 多任务学习中各loss权重应该如何设计呢 xff1f 知乎 zhihu com 多损失在深度学习中很常见 xff0c 例如 xff1a 目标检测 xff1a 以 YOLO 为例 xff0c 它的
  • YOLOv5之autoanchor看这一篇就够了

    简单粗暴 xff0c 废话也不罗嗦了 xff0c 学习目的就是解决下面三个问题 xff0c 1 默认anchor t设置为4 xff0c 这个参数如何调整 xff1f 有没有必要调整 xff1f xff08 首先网上很多说这个参数是长宽比是
  • nvidia-smi报错:NVIDIA-SMI has failed because it couldn‘t communicate with the NVIDIA driver 原因及避坑解决方案

    由于断电 xff0c 服务器重启了 xff0c 当再次跑实验时 xff0c 发现cuda不可用 xff0c 于是输入 nvidia smi 才发现了一个错误 xff0c 如下 xff1a NVIDIA SMI has failed beca
  • nvidia-smi命令输出结果缓慢问题

    nvidia smi命令输出结果缓慢问题 xff0c 可能的原因和解决办法 xff1a 1 当前已经打开了节能模式 xff08 需要关闭节能模式 xff0c 切换到持久模式 xff09 如何关闭节能模式 xff1a 方法1 xff1a su
  • PL/SQL基础(1):语法

    本篇是 Oracle基础小结 系列之一 本篇目录 1 什么是PL SQL xff1f 2 PL SQL基本结构 3 PL SQL符号定义 4 PL SQL数据类型 5 PL SQL条件句法 6 PL SQL循环 什么是PL SQL xff1
  • PL/SQL基础(2):单元

    本篇是 Oracle基础小结 系列之一 PL SQL程序单元包括 xff1a PL SQL匿名块 PL SQL函数 PL SQL存储过程 PL SQL包 PL SQL触发器等 这里就用过的几个做简单记录 xff0c 另外虽然PL SQL异常