Oracle数据库数据编程SQL<3.2 PL/SQL 匿名块中的DML操作、动态SQL、实际应用场景、使用技巧>

news2025/4/1 10:33:31

匿名块是学习和测试PL/SQL代码的强大工具,特别适合执行一次性任务或快速验证业务逻辑。

目录

一、匿名块中的DML操作

1. INSERT 示例

2. UPDATE 示例

3. DELETE 示例

二、匿名块中的动态SQL

1. EXECUTE IMMEDIATE

2. 动态游标--下篇文章会具体展开详细分享该部分内容

三、匿名块的实际应用场景

1. 数据迁移

2. 批量数据处理

3. 数据库对象检查

四、匿名块使用技巧

1. 启用DBMS_OUTPUT:

2. 调试输出:

3. 计时执行:

4. 使用绑定变量:

5. 临时禁用代码:/*...*/


一、匿名块中的DML操作

1. INSERT 示例

DECLARE
    v_emp_id NUMBER := 1001;
BEGIN
    INSERT INTO employees (employee_id, last_name, job_id, hire_date)
    VALUES (v_emp_id, 'Smith', 'IT_PROG', SYSDATE);
    
    COMMIT;
    DBMS_OUTPUT.PUT_LINE('成功插入员工: ' || v_emp_id);
EXCEPTION
    WHEN DUP_VAL_ON_INDEX THEN
        DBMS_OUTPUT.PUT_LINE('错误: 员工ID已存在');
        ROLLBACK;
END;
/

2. UPDATE 示例

DECLARE
    v_emp_id NUMBER := 100;
    v_rows_updated NUMBER;
BEGIN
    UPDATE employees
    SET salary = salary * 1.1
    WHERE employee_id = v_emp_id;
    
    v_rows_updated := SQL%ROWCOUNT;
    
    IF v_rows_updated = 0 THEN
        DBMS_OUTPUT.PUT_LINE('未找到员工记录');
    ELSE
        COMMIT;
        DBMS_OUTPUT.PUT_LINE('成功更新 ' || v_rows_updated || ' 条记录');
    END IF;
EXCEPTION
    WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE('更新失败: ' || SQLERRM);
        ROLLBACK;
END;
/

3. DELETE 示例

DECLARE
    v_dept_id NUMBER := 10;
    v_rows_deleted NUMBER;
BEGIN
    DELETE FROM employees
    WHERE department_id = v_dept_id;
    
    v_rows_deleted := SQL%ROWCOUNT;
    COMMIT;
    DBMS_OUTPUT.PUT_LINE('已删除 ' || v_rows_deleted || ' 条记录');
EXCEPTION
    WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE('删除失败: ' || SQLERRM);
        ROLLBACK;
END;
/

二、匿名块中的动态SQL

1. EXECUTE IMMEDIATE

DECLARE
    v_table_name VARCHAR2(30) := 'EMPLOYEES';
    v_sql VARCHAR2(1000);
    v_count NUMBER;
BEGIN
    v_sql := 'SELECT COUNT(*) FROM ' || v_table_name || 
              ' WHERE department_id = :dept_id';
    
    EXECUTE IMMEDIATE v_sql INTO v_count USING 10;
    
    DBMS_OUTPUT.PUT_LINE('部门10有 ' || v_count || ' 名员工');
EXCEPTION
    WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE('执行动态SQL出错: ' || SQLERRM);
END;
/

2. 动态游标--下篇文章会具体展开详细分享该部分内容

DECLARE
    TYPE emp_cur_type IS REF CURSOR;
    emp_cursor emp_cur_type;
    v_sql VARCHAR2(1000);
    v_emp_rec employees%ROWTYPE;
    v_dept_id NUMBER := 20;
BEGIN
    v_sql := 'SELECT * FROM employees WHERE department_id = :dept_id';
    
    OPEN emp_cursor FOR v_sql USING v_dept_id;
    LOOP
        FETCH emp_cursor INTO v_emp_rec;
        EXIT WHEN emp_cursor%NOTFOUND;
        DBMS_OUTPUT.PUT_LINE(v_emp_rec.employee_id || ': ' || 
                             v_emp_rec.last_name);
    END LOOP;
    CLOSE emp_cursor;
END;
/

三、匿名块的实际应用场景

1. 数据迁移

DECLARE
    CURSOR src_cur IS SELECT * FROM source_table;
    v_count NUMBER := 0;
BEGIN
    FOR rec IN src_cur LOOP
        INSERT INTO target_table VALUES rec;
        v_count := v_count + 1;
        
        -- 每1000条提交一次
        IF MOD(v_count, 1000) = 0 THEN
            COMMIT;
            DBMS_OUTPUT.PUT_LINE('已迁移 ' || v_count || ' 条记录');
        END IF;
    END LOOP;
    
    COMMIT;
    DBMS_OUTPUT.PUT_LINE('迁移完成,共 ' || v_count || ' 条记录');
EXCEPTION
    WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE('迁移出错: ' || SQLERRM);
        ROLLBACK;
END;
/

2. 批量数据处理

DECLARE
    TYPE id_array IS TABLE OF employees.employee_id%TYPE;
    v_ids id_array := id_array(101, 102, 103, 104, 105);
BEGIN
    FORALL i IN 1..v_ids.COUNT
        UPDATE employees
        SET salary = salary * 1.1
        WHERE employee_id = v_ids(i);
    
    COMMIT;
    DBMS_OUTPUT.PUT_LINE('成功更新 ' || SQL%ROWCOUNT || ' 条记录');
EXCEPTION
    WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE('批量更新失败: ' || SQLERRM);
        ROLLBACK;
END;
/

3. 数据库对象检查

DECLARE
    v_table_exists NUMBER;
    v_table_name VARCHAR2(30) := 'TEST_TABLE';
BEGIN
    SELECT COUNT(*) INTO v_table_exists
    FROM user_tables
    WHERE table_name = v_table_name;
    
    IF v_table_exists = 0 THEN
        EXECUTE IMMEDIATE 'CREATE TABLE ' || v_table_name || 
                         ' (id NUMBER, name VARCHAR2(100))';
        DBMS_OUTPUT.PUT_LINE('表 ' || v_table_name || ' 已创建');
    ELSE
        DBMS_OUTPUT.PUT_LINE('表 ' || v_table_name || ' 已存在');
    END IF;
END;
/

四、匿名块使用技巧

1. 启用DBMS_OUTPUT

SET SERVEROUTPUT ON SIZE 1000000

2. 调试输出

DBMS_OUTPUT.PUT_LINE('变量值: ' || v_variable);

3. 计时执行

DECLARE
    v_start TIMESTAMP := SYSTIMESTAMP;
BEGIN
    -- 执行代码
    DBMS_OUTPUT.PUT_LINE('执行时间: ' || (SYSTIMESTAMP - v_start));
END;
/

4. 使用绑定变量

EXECUTE IMMEDIATE 'SELECT COUNT(*) FROM employees WHERE department_id = :dept_id'
INTO v_count USING 10;

5. 临时禁用代码:/*...*/

/*
-- 被注释的代码
DBMS_OUTPUT.PUT_LINE('这段代码不会执行');
*/

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

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

相关文章

Linux中《进程状态--进程调度--进程切换》详细介绍

目录 进程状态Linux内核源代码怎么说运行&&阻塞&&挂起内核链表 进程状态查看Z(zombie)-僵尸进程僵尸进程危害孤儿进程 进程优先级进程切换Linux2.6内核进程O(1)调度队列 进程状态 Linux内核源代码怎么说 为了弄明白正在运⾏的进程是什么意思,我们…

蓝桥杯备考:多米诺骨牌

这道题要求上下方格子和之差要最小,其实就是算每个上下格子的差求和的最小值 这道题其实是动态规划01背包问题 我们直接按步骤做吧 step1:定义状态表示f[i][j]表示从1到i个编号的差值里选出刚好j个数的最小操作次数 step2:推导状态转移方程 如图这就是我们的状态…

AudioFlinger与AudioPoliceManager初始化流程

AF/APF启动流程 在启动AudioSeriver服务的过程中会对启动AF/APF。main_audioserver.cpp有如下代码: AudioFlinger::instantiate();AudioPolicyService::instantiate();AF初始化流程 1.AudioFlinger::instantiate() 1.1 AudioFlinger构造函数 void AudioFlinger:…

网路传输层UDP/TCP

一、端口号 1.端口号 1.1 五元组 端口号(port)标识了一个主机上进行通信的不同的应用程序. 如图所示, 在一个机器上运行着许多进程, 每个进程使用的应用层协议都不一样, 比如FTP, SSH, SMTP, HTTP等. 当主机接收到一个报文中, 网络层一定封装了一个目的ip标识我这台主机, …

Python大数据处理 基本的编程方法

目录 一、实验目的 二、实验要求 三、实验代码 四、实验结果 五、实验体会 一、实验目的 体会基本的python编程方法;学习python中的各类函数;了解python读取与写入文件的方法。 二、实验要求 输入2000年后的某年某月某日,判断这一天是…

STM32F103_LL库+寄存器学习笔记06 - 梳理串口与串行发送“Hello,World“

导言 USART是嵌入式非常重要的通讯方式,它的功能强大、灵活性高且用途广泛。只停留在HAL库层面上用USART只能算是入门,要加深对USART的理解,必须从寄存器层面入手。接下来,先从最简单的USART串行发送开始。 另外,在接…

硬件基础--14_电功率

电功率 电功率:指电流在单位时间内做的功(表示用电器消耗电能快慢的一个物理量)。 单位:瓦特(W),简称瓦。 公式:PUI(U为电压,单位为V,i为电流,单位为A,P为电功率,单位为W)。 单位换算:进位为1000&#xff…

Vue.js 完全指南:从入门到精通

1. Vue.js 简介 1.1 什么是 Vue.js? Vue.js(通常简称为 Vue)是一个用于构建用户界面的渐进式 JavaScript 框架。所谓"渐进式",意味着 Vue 的设计是由浅入深的,你可以根据自己的需求选择使用它的一部分或全部功能。 Vue 最初由尤雨溪(Evan You)在 2014 年创…

在Git仓库的Readme上增加目录页

一般在编写Readme时想要增加像文章那样的目录,方便快速跳转,但是Markdown语法并没有提供这样的方法,但是可以通过超链接结合锚点的方式来实现,如下图是我之前一个项目里写的Readme: 例如有下面几个Readme内容&#xff…

C# SolidWorks 二次开发 -各种菜单命令增加方式

今天给大家讲一讲solidworks中各种菜单界面,如下图,大概有13处,也许还不完整哈。 1.CommandManager选项卡2.下拉选项卡3.菜单栏4.下级菜单5.浮动工具栏6.快捷方式工具栏7.FeatureManager工具栏区域8.MontionManager区域 ModelView?9.任务窗…

【RocketMQRocketMQ Dashbord】Springboot整合RocketMQ

【RocketMQ&&RocketMQ Dashbord】Springboot整合RocketMQ 【一】Mac安装RocketMQ和RocketMQ Dashbord【1】安装RocketMQ(1)下载(2)修改 JVM 参数(3)启动测试(4)关闭测试&…

《白帽子讲 Web 安全》之跨站请求伪造

引言 在数字化时代,网络已深度融入人们生活的方方面面,Web 应用如雨后春笋般蓬勃发展,为人们提供着便捷高效的服务。然而,繁荣的背后却潜藏着诸多安全隐患,跨站请求伪造(CSRF)便是其中极为隐蔽…

K8S学习之基础五十:k8s中pod时区问题并通过kibana查看日志

k8s中pod默认时区不是中国的,挂载一个时区可以解决 vi pod.yaml apiVersion: v1 kind: Pod metadata:name: counter spec:containers:- name: countimage: 172.16.80.140/busybox/busybox:latestimagePullPolicy: IfNotPresentargs: [/bin/sh,-c,i0;while true;do …

nginx代理前端请求

一,项目配置 我在 ip 为 192.168.31.177 的机器上使用 vue3 开发前端项目,项目中使用 axios 调用后端接口。 这是 axios 的配置: import axios from axios;const request axios.create({baseURL: http://192.168.31.177:8001,// 设置请求…

Android生态大变革,谷歌调整开源政策,核心开发不再公开

“开源”这个词曾经是Android的护城河,如今却成了谷歌的烫手山芋。最近谷歌宣布调整Android的开源政策,核心开发将全面转向私有分支。翻译成人话就是:以后Android的核心更新,不再公开共享了。 这操作不就是开源变节吗,…

银行分布式新核心的部署架构(两地三中心)

银行的核心系统对可用性和性能要求均非常严苛,所以一般都采用两地三中心部署模式。 其中: 同城两个主数据中心各自部署一套热备,平时两个中心同时在线提供服务,进行负载均衡假如其中一个数据中心出现异常,则由另外一个…

MantisBT在Windows10上安装部署详细步骤

MantisBT 是一款基于 Web 的开源缺陷跟踪系统,以下是在 Windows 10 上安装部署 MantisBT 的详细步骤: 1. 安装必要的环境 MantisBT 是一个基于 PHP 的 Web 应用程序,因此需要安装 Web 服务器(如 Apache)、PHP 和数据…

9.4分漏洞!Next.js Middleware鉴权绕过漏洞安全风险通告

今日,亚信安全CERT监控到安全社区研究人员发布安全通告,Next.js 存在一个授权绕过漏洞,编号为 CVE-2025-29927。攻击者可能通过发送精心构造的 x-middleware-subrequest 请求头绕过中间件安全控制,从而在未授权的情况下访问受保护…

OpenCV图像拼接(5)图像拼接模块的用于创建权重图函数createWeightMap()

操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 cv::detail::createWeightMap 是 OpenCV 库中用于图像拼接模块的一个函数,主要用于创建权重图。这个权重图在图像拼接过程中扮演着重…

CTF类题目复现总结-[MRCTF2020]ezmisc 1

一、题目地址 https://buuoj.cn/challenges#[MRCTF2020]ezmisc二、复现步骤 1、下载附件,得到一张图片; 2、利用010 Editor打开图片,提示CRC值校验错误,flag.png应该是宽和高被修改了,导致flag被隐藏掉;…