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

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

匿名块是学习和测试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.dtcms.com/a/99061.html

相关文章:

  • matplotlib标题比x,y轴字体大,明明标题字体更大?
  • pr--打开视频后没有声音输出
  • VBA第三十三期 如何在VBA中运行Access
  • 大模型评测框架evalscope、openCompass
  • Redis 源码硬核解析系列专题 - 第一篇:Redis源码入门与整体架构
  • 5000元组装一台本地运行中、小模型主机,参考配置 (运行DeepSeek、Qwen)
  • 前缀和c++
  • 2两数相加解题记录
  • Nyquist插件基础:打印格式化字符串(LISP语言)
  • Java虚拟机(JVM)详解
  • 前端 vue 项目上线前操作
  • Spring Cache:简化缓存管理的抽象框架
  • MCP, LangChain、Dify 区别
  • 3.30日 001:中央海岸VS珀斯光荣
  • 操作系统 :进程概念
  • 集多功能为一体的软件,支持批量操作。
  • web权限划分提权和移权
  • 自行车模型与汽车模型的混合策略在自动驾驶中的多维度协同优化
  • graylog使用过程中的几个问题
  • 根据二叉树创建字符串
  • Linux的进程优先级调度学习笔记
  • 智慧运维平台:赋能未来,开启高效运维新时代
  • React 中props的不可变性,如何在组件中处理需要修改props的情况?
  • 每日一题 MySQL基础知识----(三)
  • 饮食 “妙方”,助力进行性核上性麻痹调养
  • 学校智慧路灯的主要功能有哪些?
  • Python第六章19:函数的多种参数类型对比
  • 【嵌入式学习3】零散知识点
  • 【C++篇】类与对象(上篇):从面向过程到面向对象的跨越
  • 【8】递归之经典题型总结