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

Oracle-动态sql学习笔记,由易至难讲解七个例子

本文章的内容来源于对oracle课堂上讲的内容做出的笔记

静态sql和动态sql

·静态sql:

静态 SQL 是在编译时写死的 SQL 语句,即在程序编写阶段,SQL 语句已经被固定下来。

特点:

1.预编译: SQL 语句在程序编译时就会被解析、优化,并生成执行计划,然后存储在数据库中。
2.性能: 由于编译时已经确定了执行计划,因此执行时性能相对较高,因为不需要解析和生成执行计划。
3.安全性: 相对较高,因为 SQL 语句是在编译时确定的,不容易受到 SQL 注入等攻击。

例子:

SELECT * FROM employees WHERE department_id = 10;

·动态sql:

动态 SQL 是在运行时构建和执行的 SQL 语句,允许根据程序运行时的条件来生成不同的 SQL 语句

特点:

1.灵活性: 允许在运行时动态构建 SQL 语句,根据需要进行条件判断、循环等,使得程序更加灵活。
2.执行计划: SQL 语句在运行时解析和生成执行计划,可能会导致一些性能损失,因为这个过程在运行时发生。
3.安全性: 相对较低,因为动态 SQL 可能会受到 SQL 注入攻击,必须谨慎处理输入的参数。

DECLAREv_department_id NUMBER := 10;v_sql_statement VARCHAR2(100);
BEGINv_sql_statement := 'SELECT * FROM employees WHERE department_id = ' || v_department_id;EXECUTE IMMEDIATE v_sql_statement;
END;

什么时候使用动态sql

1.由于在PL/SQL中只能执行静态的查询和DML语句,因此要执行DDL语句或DCL语句,必须借助于动态SQL语句
2.在开发报表或一些复杂的应用程序逻辑时,如果要基于参数化的查询方式,比如动态的表字段和动态的表名称时,可以使用动态SQL语句
3.基于数据表存储业务规则和软件代码,可以将很多的业务规则的代码写在一个表的记录中,在程序需要时检索不同的业务逻辑代码动态的执行

下面用几个例子,从简单到复杂讲解动态sql的几种使用

例子一讲解(基础)

DECLARE
sql_stmt1 VARCHAR2(128);
BEGIN
sql_stmt1:='INSERT INTO rooms 
VALUES (99000, ''Building 7'', 110, 50, ''Discussion Room E'')';
EXECUTE IMMEDIATE sql_stmt1;
COMMIT;
END;

sql_stmt1 被赋予一个包含 INSERT 语句的字符串。这个 INSERT 语句的目的是向名为 rooms 的表中插入一行记录,包括房间号、建筑名称、楼层、容量和房间类型等信息。EXECUTE IMMEDIATE 语句用于在运行时执行动态生成的 SQL 语句。在这里,它执行了 sql_stmt1 中存储的 INSERT 语句,COMMIT是提交事务的命令。在数据库操作中,当你执行一些修改数据的操作时,比如 INSERT、UPDATE 或 DELETE,最后需要使用 COMMIT 语句来确保这些修改永久保存到数据库中

例子二讲解(使用绑定变量)

DECLAREv_department_id NUMBER;v_department_name VARCHAR2(100);v_sql_statement VARCHAR2(200);
BEGIN-- 使用 & 符号定义输入参数v_department_id := &input_department_id;-- 构建动态SQL语句,使用 :department_id 作为绑定变量v_sql_statement := 'SELECT department_name FROM departments WHERE department_id = :department_id';-- 执行动态SQL语句,并将输入的部门ID传递给绑定变量 :department_idEXECUTE IMMEDIATE v_sql_statement INTO v_department_name USING v_department_id;-- 输出查询结果DBMS_OUTPUT.put_line('部门名称为: ' || v_department_name);
END;

在这个示例中,&input_department_id 是一个替换变量,当代码运行时,系统将提示用户输入一个部门ID。这个输入的部门ID将被赋值给v_department_id,然后用作动态SQL语句中的绑定变量:department_id。这样,在执行动态SQL语句时,用户输入的值将被正确地用于查询操作,最后结果会显示查询到的部门名称。

这种方式对于需要用户交互式输入参数来动态构建SQL语句的情况非常有用,可以根据用户输入灵活地执行查询或其他数据库操作,需要注意的是:

这个地方的冒号以及后面的一堆字符串(遇见空格结束)合起来代表一个占位符,后面这个字符串是可以随意取名的,最后使用USING这个关键字放替代这个占位符的真正的变量,当然,当有多个绑定变量的时候,可以放多个占位符,然后,using后面也可以跟多个变量,用逗号分割

例子三讲解(执行动态PL/SQL块)

DECLARE
plsql_block VARCHAR2(500);
BEGIN
plsql_block := '
BEGIN 
EXECUTE IMMEDIATE ''TRUNCATE TABLE temp_table'';
FOR v_Counter IN 1..50 LOOP
INSERT INTO temp_table
VALUES (v_Counter, ''Loop Index'');
END LOOP; 
END;';
EXECUTE IMMEDIATE plsql_block;
COMMIT;
END;

这个代码执行的内容实际上是plsql_block字符串当中的语句,首先会对temp_table进行TRUNCATE(截断),然后在表中插入50行数据

例子四讲解(使用RETURNING INTO

DECLARE
sql_stmt1 VARCHAR2(500);
v_room_id NUMBER(5):=99994;
v_number_seats NUMBER(4);
BEGIN
sql_stmt1:='UPDATE rooms SET number_seats=number_seats+10'
|| ' WHERE room_id=:room_id RETURNING number_seats 
INTO :number_seats';
EXECUTE IMMEDIATE sql_stmt1 USING v_room_id 
RETURNING INTO v_number_seats;
DBMS_OUTPUT.put_line('调整后的座位数量为:'|| v_number_seats);
COMMIT;
END;

使用 EXECUTE IMMEDIATE 执行存储在 sql_stmt1 中的动态 SQL 语句。通过 USING 子句将 v_room_id 绑定到 :room_id 参数,通过 RETURNING INTO 子句将更新后的 number_seats 返回到 v_number_seats 变量中

例子五讲解(OPEN...FOR处理多行查询)

DECLARE
sql_stmt1 VARCHAR2(500);
TYPE t_RSCurType IS REF CURSOR;
v_rs_cursor t_RSCurType;
v_student_id NUMBER(5):=10000;
v_rs_record registered_students%ROWTYPE;
BEGIN
sql_stmt1 :=' SELECT student_id,department,course,grade FROM 
registered_students WHERE student_id= :student_id';
OPEN v_rs_cursor FOR sql_stmt1 USING v_student_id;
LOOP
FETCH v_rs_cursor INTO v_rs_record;
EXIT WHEN v_rs_cursor%NOTFOUND;
DBMS_OUTPUT.put_LINE('学号:' || v_rs_record.student_id || 
' ' || '系:' ||v_rs_record.department ||' 课程:' || v_rs_record.course 
||' 分数:' || v_rs_record.grade);
END LOOP;
CLOSE v_rs_cursor;
END;

t_RSCurType 是一个游标类型的声明,用于定义 v_rs_cursor 的数据类型。
v_rs_cursor 是一个 REF CURSOR 类型的游标变量。
v_student_id 是一个 NUMBER 类型的变量,赋值为 10000。
v_rs_record 是一个记录类型,用于存储 registered_students 表的一行数据。

使用 OPEN 语句打开游标,并使用 USING 子句将参数 v_student_id 绑定到 SQL 语句中的 :student_id,使用 LOOP 开始循环,通过 FETCH 语句从游标中获取数据,并将其存储到 v_rs_record 变量中。循环会在游标到达结果集的末尾时退出, 使用 CLOSE 语句关闭游标。

EXIT WHEN v_rs_cursor%NOTFOUND意思为搜到结尾就退出

总之,整个代码的作用是查询指定学生的信息并逐行输出。这里使用了动态 SQL,通过参数 v_student_id 绑定到 SQL 语句中,并且游标用于逐行处理查询结果。输出使用 DBMS_OUTPUT 函数,这通常用于在调试时输出信息

例子六讲解(批量绑定)

动态SQL批量绑定指的是在执行动态SQL语句时,一次性处理多个绑定变量值,而不是逐个处理

DECLARE
sql_stmt1 VARCHAR2(500);
TYPE t_student_id IS TABLE OF students.id%TYPE INDEX BY 
BINARY_INTEGER;
TYPE t_first_name IS TABLE OF students.first_name%TYPE INDEX 
BY BINARY_INTEGER;
TYPE t_last_name IS TABLE OF students.last_name%TYPE INDEX 
BY BINARY_INTEGER;
v_student_id_tab t_student_id;
v_first_name_tab t_first_name;
v_last_name_tab t_last_name;
v_major students.major%TYPE:=‘History‘;
BEGIN
sql_stmt1 :=' SELECT student_id,first_name,last_name FROM students 
WHERE major= :major'; 
EXECUTE IMMEDIATE sql_stmt1
BULK COLLECT INTO 
v_student_id_tab,v_first_name_tab,v_last_name_tab
USING v_major;
FOR i IN 1..v_student_id_tab.COUNT LOOP
DBMS_OUTPUT.put_line('学号:' || v_student_id_tab(i) ||' ' || '名:' 
||v_first_name_tab(i) ||' 姓:' || v_last_name_tab(i));
END LOOP;
END;

t_student_id、t_first_name、t_last_name 是三个关联数组的类型定义,索引类型为 BINARY_INTEGER。
v_student_id_tab、v_first_name_tab、v_last_name_tab 是实际的关联数组变量,所谓关联数组,以v_student_id_tab为例,简单来说就是一个数据类型和“students表当中的id”一样的元素的集合

使用 EXECUTE IMMEDIATE 执行动态 SQL 查询,并通过 BULK COLLECT INTO 子句将查询结果批量收集到关联数组中。USING 子句将 v_major 绑定到 SQL 语句中,然后使用 FOR 循环遍历关联数组,逐行输出学生的学号、名字和姓氏

整个代码的作用是查询指定专业的学生信息,并通过关联数组将学号、名字和姓氏分别存储,并通过循环逐行输出。请注意,动态 SQL 的使用使得 SQL 语句在运行时构建,而不是在编译时

例子七讲解(使用RETURNING BULK COLLECT INTO)

DECLARE
sql_stmt1 VARCHAR2(500);
TYPE t_room_id IS TABLE OF rooms.room_id%TYPE INDEX BY 
BINARY_INTEGER;
TYPE t_number_seats IS TABLE OF rooms.number_seats%TYPE 
INDEX BY BINARY_INTEGER;
v_room_id_tab t_room_id;
v_number_seats_tab t_number_seats;
v_building rooms.building%TYPE := 'Music Building';
BEGIN
sql_stmt1:='UPDATE rooms SET number_seats=number_seats+10'
|| ' WHERE building=:building RETURNING 
room_id,number_seats INTO :room_id,:number_seats';
EXECUTE IMMEDIATE sql_stmt1 USING v_building
RETURNING BULK COLLECT INTO 
v_room_id_tab,v_number_seats_tab;
FOR i IN 1..v_room_id_tab.COUNT LOOP
DBMS_OUTPUT.put_line('教室编号:'||v_room_id_tab(i) ||'调整后的
座位数量为:'|| v_number_seats_tab(i));
END LOOP;
COMMIT;
END;

整个代码块的作用是动态地更新符合条件的教室的座位数量,并通过关联数组存储并输出更新后的教室编号和座位数量。请注意,动态 SQL 的使用使得 SQL 语句在运行时构建,而不是在编译时,很多比如说关联数组的用法跟例子六相似,仅仅需要提的是这里使用动态 SQL 构建更新语句,将满足条件的教室的座位数量增加10,并通过 RETURNING INTO 子句将更新后的教室编号和座位数量返回到关联数组中

相关文章:

Oracle-动态sql学习笔记,由易至难讲解七个例子

本文章的内容来源于对oracle课堂上讲的内容做出的笔记 静态sql和动态sql 静态sql: 静态 SQL 是在编译时写死的 SQL 语句,即在程序编写阶段,SQL 语句已经被固定下来。 特点: 1.预编译: SQL 语句在程序编译时就会被…...

Kafka 的应用场景

Kafka 是一个开源的分布式流式平台,它可以处理大量的实时数据,并提供高吞吐量,低延迟,高可靠性和高可扩展性。 Kafka 最初是为分布式系统中海量日志处理而设计的。它可以通过持久化功能将消息保存到磁盘,并让消费者按…...

保驾“双十一” 博睿数据助力电商零售迎高峰无烦忧

如果说“双十一”大战的A面是由天猫、京东、拼多多、唯品会等电商平台,以及一些MCN机构、头部主播拉动的一系列购物狂潮,那么B面则是零售、物流、制造、银行保险等全产业链面对海量流量之下,以强大的心力、脑力与体力应对流量增加和交易陡增的…...

F.binary_cross_entropy、nn.BCELoss、nn.BCEWithLogitsLoss与F.kl_div函数详细解读

提示:有关loss损失函数详细解读,并附源码!!! 文章目录 前言一、F.binary_cross_entropy()函数解读1.函数表达2.函数运用 二、nn.BCELoss()函数解读1.函数表达2.函数运用 三、nn.BCEWithLogitsLoss()函数解读1.函数表达…...

后端接口性能优化分析

👏作者简介:大家好,我是爱吃芝士的土豆倪,24届校招生Java选手,很高兴认识大家📕系列专栏:Spring源码、JUC源码🔥如果感觉博主的文章还不错的话,请👍三连支持&…...

【ceph】ceph集群中使用多路径(Multipath)方法

本站以分享各种运维经验和运维所需要的技能为主 《python零基础入门》:python零基础入门学习 《python运维脚本》: python运维脚本实践 《shell》:shell学习 《terraform》持续更新中:terraform_Aws学习零基础入门到最佳实战 《k8…...

Xshell+Xftp通过代理的方式访问局域网内网服务器

最近在部署项目时遇到只有1台服务器拥有公网ip,其它服务器只有局域网ip,当然其它服务器可以正常访问网络,例如如下模型。之前访问其它几台服务器,都是先通过登录公网IP服务器,然后在Xshell里面执行ssh远程连接&#xf…...

对盒子中的材料进行计数

背景 在做AI算法分析项目的时候,有时候需要我们使用影像分析结合机器学习算法对某些材料盒中的材料进行数目计数,通过自己的分析,给出以下两种解决问题的思路。 1.图像处理方法对材料计数 要使用图像处理方式对盒子中的材料进行数目分析&a…...

科技驱动固定资产管理变革:RFID技术的前沿应用

在当今激烈竞争的商业环境中,企业固定资产管理面临挑战,而RFID技术正以其独特特性和功能性彻底改变资产管理方式。本文将深入探讨RFID技术在固定资产管理中的革命性作用,并解析其应用带来的创新和便利。 RFID技术概述: RFID系统作…...

Django路由层之有名分组和无名分组、反向解析、路由分发、伪静态的概念、名称空间、虚拟环境、Django1和Django2的区别

【1】无名分组 无名分组:就是把正则中小括号里噩匹配到的内容以位置参数的形式传递给视图函数 url(r^test/(\d)$,view.text) get请求的第一种方式: http://127.0.0.1:8000/test/?a1&b2 get请求的第二种方式: http://127.0.0.1:8000/test…...

【nlp】2.5 人名分类器实战项目(对比RNN、LSTM、GRU模型)

人名分类器实战项目 0 项目说明1 案例介绍2 案例步骤2.1 导入必备的工具包2.2 数据预处理2.2.1 获取常用的字符数量2.2.2 国家名种类数和个数2.2.3 读数据到python环境中2.2.4 构建数据源NameClassDataset2.2.5 构建迭代器遍历数据2.3 构建RNN及其变体模型2.3.1 构建RNN模型2.3…...

海康Visionmaster-环境配置:MFC 二次开发环境配置方法

1 新建 MFC 工程,拷贝 DLL:VM\VisionMaster4.0.0\Development\V4.0.0 \ComControl\bin\x64 下的所有拷贝到项目工程输出目录下,如下图所示,项目的输出路径是 Dll 文件夹。 2 通过配置 C目录和链接器的方式配置 VM 环境 2.1 C目录下添加附加…...

利用EXCEL中的VBA对同一文件夹下的多个数据文件进行特定提取

Sub CopyFilesBasedOnCriteria()Dim fso As ObjectDim sourceFolder As StringDim destinationFolder As String 设置源文件夹路径和目标文件夹路径sourceFolder "C:\\test\\全波段模拟_Nimbostratus cloud - 副本"destinationFolder "C:\\Desktop\\MOD02数据…...

FPGA时序约束(七)文献时序约束实验测试

系列文章目录 文章目录 系列文章目录前言文献1:时钟移位LogiclockDesign Partition封装用户编写的程序停掉singletap抓取单端口RAM的数据文献2:SRAM约束前言 之前学习了一些基本时序约束的类别,包括主时钟约束、虚拟时钟约束、输入输出约束、多周期约束等等,但大多都是纸上…...

【数据库开发】DataX开发环境的安装部署(Python、Java)

文章目录 1、简介1.1 DataX简介1.2 DataX功能1.3 支持的数据通道 2、DataX安装配置2.1 DataX2.2 Java2.3 Python 3、DataX Web安装配置3.1 mysql3.2 DataX Web3.2.1 简介3.2.2 架构图3.2.3 依赖环境3.2.4 安装 4、入门使用4.1 DataX自带打印示例测试4.2 DataX生成任务模板文件4…...

Flutter实践一:package组织

1.架构概览 为了降低Flutter工程里lib的复杂度,应尽量拆分一些代码成为独立的package。如图: 我们将通用的组件、领域模型、API、features、存储、repository等抽取成了单独的package。这时lib只剩下多国语言、基本的页面、路由等代码了: 这…...

SpringCloud微服务:Ribbon负载均衡

目录 负载均衡策略: 负载均衡的两种方式: 饥饿加载 1. Ribbon负载均衡规则 规则接口是IRule 默认实现是ZoneAvoidanceRule,根据zone选择服务列表,然后轮询 2.负载均衡自定义方式 代码方式:配置灵活,但修…...

【教程】大气化学在线耦合模式WRF/Chem

查看原文>>>区域气象-大气化学在线耦合模式(WRF/Chem)在大气环境领域实践 随着我国经济快速发展,我国面临着日益严重的大气污染问题。近年来,严重的大气污染问题已经明显影响国计民生,引起政府、学界和人们越…...

GDS 命令的使用 srvctl service TAF application continuity

文档中prim and stdy在同一台机器上,不同机器需要添加address list TAF ENABLED GLOBAL SERVICE in GDS ENVIRONMNET 12C. (Doc ID 2283193.1)​编辑To Bottom In this Document Goal Solution APPLIES TO: Oracle Database - Enterprise Edition - Version 12.1.…...

go 语言之 select

在 Go 语言中&#xff0c;select 是一种用于处理多个通道操作的控制结构。它可以用于在多个通道之间进行非阻塞的选择操作&#xff0c;从而实现并发控制和通信。 select 语句的基本语法如下&#xff1a; go select { case <-channel1:// 当 channel1 可读时执行的代码 cas…...

RestClient

什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端&#xff0c;它允许HTTP与Elasticsearch 集群通信&#xff0c;而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级&#xff…...

19c补丁后oracle属主变化,导致不能识别磁盘组

补丁后服务器重启&#xff0c;数据库再次无法启动 ORA01017: invalid username/password; logon denied Oracle 19c 在打上 19.23 或以上补丁版本后&#xff0c;存在与用户组权限相关的问题。具体表现为&#xff0c;Oracle 实例的运行用户&#xff08;oracle&#xff09;和集…...

《从零掌握MIPI CSI-2: 协议精解与FPGA摄像头开发实战》-- CSI-2 协议详细解析 (一)

CSI-2 协议详细解析 (一&#xff09; 1. CSI-2层定义&#xff08;CSI-2 Layer Definitions&#xff09; 分层结构 &#xff1a;CSI-2协议分为6层&#xff1a; 物理层&#xff08;PHY Layer&#xff09; &#xff1a; 定义电气特性、时钟机制和传输介质&#xff08;导线&#…...

高等数学(下)题型笔记(八)空间解析几何与向量代数

目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...

相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)

【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...

智能仓储的未来:自动化、AI与数据分析如何重塑物流中心

当仓库学会“思考”&#xff0c;物流的终极形态正在诞生 想象这样的场景&#xff1a; 凌晨3点&#xff0c;某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径&#xff1b;AI视觉系统在0.1秒内扫描包裹信息&#xff1b;数字孪生平台正模拟次日峰值流量压力…...

招商蛇口 | 执笔CID,启幕低密生活新境

作为中国城市生长的力量&#xff0c;招商蛇口以“美好生活承载者”为使命&#xff0c;深耕全球111座城市&#xff0c;以央企担当匠造时代理想人居。从深圳湾的开拓基因到西安高新CID的战略落子&#xff0c;招商蛇口始终与城市发展同频共振&#xff0c;以建筑诠释对土地与生活的…...

Golang——6、指针和结构体

指针和结构体 1、指针1.1、指针地址和指针类型1.2、指针取值1.3、new和make 2、结构体2.1、type关键字的使用2.2、结构体的定义和初始化2.3、结构体方法和接收者2.4、给任意类型添加方法2.5、结构体的匿名字段2.6、嵌套结构体2.7、嵌套匿名结构体2.8、结构体的继承 3、结构体与…...

TSN交换机正在重构工业网络,PROFINET和EtherCAT会被取代吗?

在工业自动化持续演进的今天&#xff0c;通信网络的角色正变得愈发关键。 2025年6月6日&#xff0c;为期三天的华南国际工业博览会在深圳国际会展中心&#xff08;宝安&#xff09;圆满落幕。作为国内工业通信领域的技术型企业&#xff0c;光路科技&#xff08;Fiberroad&…...

【Linux】自动化构建-Make/Makefile

前言 上文我们讲到了Linux中的编译器gcc/g 【Linux】编译器gcc/g及其库的详细介绍-CSDN博客 本来我们将一个对于编译来说很重要的工具&#xff1a;make/makfile 1.背景 在一个工程中源文件不计其数&#xff0c;其按类型、功能、模块分别放在若干个目录中&#xff0c;mak…...