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远程连接…...
对盒子中的材料进行计数
背景 在做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 语言中,select 是一种用于处理多个通道操作的控制结构。它可以用于在多个通道之间进行非阻塞的选择操作,从而实现并发控制和通信。 select 语句的基本语法如下: go select { case <-channel1:// 当 channel1 可读时执行的代码 cas…...
java_网络服务相关_gateway_nacos_feign区别联系
1. spring-cloud-starter-gateway 作用:作为微服务架构的网关,统一入口,处理所有外部请求。 核心能力: 路由转发(基于路径、服务名等)过滤器(鉴权、限流、日志、Header 处理)支持负…...
DockerHub与私有镜像仓库在容器化中的应用与管理
哈喽,大家好,我是左手python! Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库,用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...
【磁盘】每天掌握一个Linux命令 - iostat
目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat(I/O Statistics)是Linux系统下用于监视系统输入输出设备和CPU使…...

[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?
论文网址:pdf 英文是纯手打的!论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误,若有发现欢迎评论指正!文章偏向于笔记,谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...
Neo4j 集群管理:原理、技术与最佳实践深度解析
Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...

零基础在实践中学习网络安全-皮卡丘靶场(第九期-Unsafe Fileupload模块)(yakit方式)
本期内容并不是很难,相信大家会学的很愉快,当然对于有后端基础的朋友来说,本期内容更加容易了解,当然没有基础的也别担心,本期内容会详细解释有关内容 本期用到的软件:yakit(因为经过之前好多期…...
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数 在软件开发中,单例模式(Singleton Pattern)是一种常见的设计模式,确保一个类仅有一个实例,并提供一个全局访问点。在多线程环境下,实现单例模式时需要注意线程安全问题,以防止多个线程同时创建实例,导致…...

给网站添加live2d看板娘
给网站添加live2d看板娘 参考文献: stevenjoezhang/live2d-widget: 把萌萌哒的看板娘抱回家 (ノ≧∇≦)ノ | Live2D widget for web platformEikanya/Live2d-model: Live2d model collectionzenghongtu/live2d-model-assets 前言 网站环境如下,文章也主…...

关于easyexcel动态下拉选问题处理
前些日子突然碰到一个问题,说是客户的导入文件模版想支持部分导入内容的下拉选,于是我就找了easyexcel官网寻找解决方案,并没有找到合适的方案,没办法只能自己动手并分享出来,针对Java生成Excel下拉菜单时因选项过多导…...

android RelativeLayout布局
<?xml version"1.0" encoding"utf-8"?> <RelativeLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"match_parent"android:layout_height"match_parent"android:gravity&…...